Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
toiletbrush
May 17, 2010

Dylan16807 posted:

Not all floating point calculations. Only ones that involve fractional numbers. Integer math works just as well as it always does.
No it doesn't...

code:
int x = 100000000;
Console.WriteLine((x + 1) - x);

float y = 100000000;
Console.WriteLine((y + 1) - y);

toiletbrush fucked around with this message at 15:55 on Sep 14, 2016

Adbot
ADBOT LOVES YOU

robostac
Sep 23, 2009

Dylan16807 posted:

When has moving to another architecture broken floating point code? Almost everything is IEEE standard, and good luck porting to a weird DSP without already having to rewrite your code. FDIV doesn't count; particular processor models have broken instructions all the time.

From that series of articles above (https://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/) - basically the IEE standards specify how to store the final results, but not how to store intermediates, so precision errors are often different.

Dylan16807
May 12, 2010

toiletbrush posted:

No it doesn't...

code:
int x = 100000000;
Console.WriteLine((x + 1) - x);

float y = 100000000;
Console.WriteLine((y + 1) - y);

What size is int here? If it's 32 bits then you're just showing off that 32 bits of precision is better than 24.

If int is 24 bits here, then you found a flaw in my argument, that ints can have better behavior when you're overflowing them. Of course, ints can also cause much worse behavior when overflowing. Especially in C, where that's undefined behavior.

Still, most code doesn't need wrapping overflow semantics, and can do integer math in floating point formats just fine.

Dylan16807
May 12, 2010

robostac posted:

From that series of articles above (https://randomascii.wordpress.com/2012/03/21/intermediate-floating-point-precision/) - basically the IEE standards specify how to store the final results, but not how to store intermediates, so precision errors are often different.

The handling of intermediates can also vary by things like stack layout and compiler flags, especially on x86. I would expect any code written carefully enough to always get the same results on one platform to survive a transition to other platforms with minimal effort. I could be wrong on that, but this is the first time I've heard of portability concerns as a reason to be wary of IEEE floating point.

antpocas
Jun 30, 2004

IF THIS POST ISN'T ABOUT GLORIOUS SALAZAR YOU MUST BE READING IT WRONG
code:
urlPortal = (urlPortal.LastIndexOf("/", StringComparison.Ordinal) >= (urlPortal.Length - 1)) ? urlPortal : urlPortal + "/";
what the gently caress

Linear Zoetrope
Nov 28, 2011

A hero must cook
I mean, usually if you're really, really concerned about precision you either normalize your range of numbers to lower values where float works a little more reasonably, or you switch to some other rational/symbolic/scaled-integer-based representation.

fritz
Jul 26, 2003

Dylan16807 posted:

When has moving to another architecture broken floating point code?
Seventh google link:
https://software.intel.com/en-us/forums/intel-c-compiler/topic/518464

Dylan16807
May 12, 2010

That's code that gives different results on the same processor based on an environment variable. I'd say it's the opposite of code that's non-broken on one architecture and breaks when you port it to another.

Also they're both x86_64, not exactly what I meant when talking about architectures in reply to porting to ARM.

But it is a good example of how it's often hard to use (non-integer) floating point numbers correctly in the first place.

Not that any alternative is easy to use either.

toiletbrush
May 17, 2010

Dylan16807 posted:

What size is int here? If it's 32 bits then you're just showing off that 32 bits of precision is better than 24.

If int is 24 bits here, then you found a flaw in my argument, that ints can have better behavior when you're overflowing them. Of course, ints can also cause much worse behavior when overflowing. Especially in C, where that's undefined behavior.

Still, most code doesn't need wrapping overflow semantics, and can do integer math in floating point formats just fine.
I'm not talking about overflow semantics. I'm saying 'Integer math works just as well as it always does' is untrue, because the effects of fp rounding are way more subtle and complicated than integer overflow - even simple addition/subtraction of integers in fp falls apart surprisingly quickly.

Dylan16807
May 12, 2010

toiletbrush posted:

I'm not talking about overflow semantics. I'm saying 'Integer math works just as well as it always does' is untrue, because the effects of fp rounding are way more subtle and complicated than integer overflow - even simple addition/subtraction of integers in fp falls apart surprisingly quickly.

Those are overflow semantics. If you don't overflow the 24 or 53 bits you get in a float or double, it won't round.

Integer overflow is not simple either. Do it in C and the program can make up whatever number it wants, or return halfway through the function, or crash.

Most of the time, you should not be overflowing. It will break no matter whether it's int or float. It will just break differently.

toiletbrush
May 17, 2010

Dylan16807 posted:

Those are overflow semantics. If you don't overflow the 24 or 53 bits you get in a float or double, it won't round.
You're right, that is overflow. But I think my point stands...or maybe not. Happy to be told I'm wrong on this one.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

hackbunny posted:

To write a program with an infinite loop, do you need source code of infinite length? 0.6̅ is hardly infinite, and there is a simple formula to go from that form to the fraction and back.

Revised quote because apparently this is nitpicker's corner in the comedy coding horrors forum: Every fraction that has a denominator that doesn't have roots 2 or 5 is unrepresentable in decimal notation, with a finite number of significands, and without repeating decimal notation.

My point is that 1/5 being unrepresentable in finite binary notation is the same as 1/3 being unrepresentable in finite decimal notation. Floating point is basically "scientific notation" with a finite number of significant figures. 53, in fact. It's powers of two instead of powers of ten, but, yes, all integers in that range are representable, and the fact that people don't understand that mean that we're not teaching floating points right.

Space Kablooey
May 6, 2009


antpocas posted:

code:
urlPortal = (urlPortal.LastIndexOf("/", StringComparison.Ordinal) >= (urlPortal.Length - 1)) ? urlPortal : urlPortal + "/";
what the gently caress

EndsWith is too hard, man.

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Suspicious Dish posted:

Would you say that everyday decimal numbers are fuzzy, approximate things? Every fraction that has a denominator that doesn't have roots 2 or 5 is unrepresentable in decimal.

I used the word "heuristic" twice, what more do you want?

And if you've ever done math involving multiple steps with a calculator and writing down intermediate values, then yes the result can be fuzzy. I've seen students using the same numbers and formulas get different results due to the order they perform the steps in, the number of operations they combine, the point at which they truncate intermediate results, etc. In fact the software we used to administer assignments didn't insist on exact results for this reason, so yes treating decimal numbers as fuzzy and approximate is a useful heuristic just as it is with floats.

return0
Apr 11, 2007

ulmont posted:

Pretty sure both have been posted here before, but helpful links regarding floating point:

1) A long (16 part) series with more than you would ever want to know about floating point weirdnesses.
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

Article from same stating that floating point ain't magic and sometimes you really do want an equality comparison (as I think was the case in the function that led to this discussion):

https://randomascii.wordpress.com/2012/06/26/doubles-are-not-floats-so-dont-compare-them/

hobbesmaster
Jan 28, 2008

You know what started this is testing a variable called paramDblValue against a float literal and not a double.

fritz
Jul 26, 2003

Dylan16807 posted:

That's code that gives different results on the same processor based on an environment variable. I'd say it's the opposite of code that's non-broken on one architecture and breaks when you port it to another.

Also they're both x86_64, not exactly what I meant when talking about architectures in reply to porting to ARM.

That's not my reading?

quote:


I am getting inconsistent floating point results when i run an application on different architecture. This happens after the third decimal point. I am able to get repeatable results on the same architecture but when i run on a different architecture i get inconsistencies in floating point results. The two architecture i'm talking about is nehalem and sandy bridge. The application is a 64 bit application. I am using Visual Studio 2013 which has Intel composer XE 2013 C++ sp1. I tried the solution recommended in the link below, but it didn't change anything. The industry in which i work, data accuracy upto 16th decimal point is extremely important. Any help is appreciated

Spatial
Nov 15, 2007

Tank Boy Ken posted:

double d2(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1); // should equal 1.0
= 0.99999999999999989
This isn't as demonstrative as it seems, it's more of a "garbage in garbage out" example. For the sake of usability the compiler is allowing you to do something which doesn't make sense. You define a value the computer can't store, which can't be used in any computation, and to help you out the compiler has picked the closest usable value for you. It wouldn't be technically wrong for it to issue 10 errors on that line because it's the equivalent of writing a 33-bit number into a 32-bit storage location.

It's not a terribly surprising output when you consider the compiler told the computer to do this:
code:
double d2(
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625 + 
0.9999999999999999955511151231257827021181583404541015625
); // should equal 1.0
But since nobody wants to see hundreds of irrelevant warnings about numerical precision loss that are a million characters long, and nobody wants to spend 10 minutes per numerical constant researching the next nearest representable number in binary to write down, that's the wholly reasonable compromise we're left with.

Dylan16807
May 12, 2010

fritz posted:

That's not my reading?

First note that "different" architectures are both x86_64. Then read the post talking about MKL_CBWR. It's not the CPU causing problems here, it's the library switching to a different mode.

return0
Apr 11, 2007

hobbesmaster posted:

You know what started this is testing a variable called paramDblValue against a float literal and not a double.

Yeah but comparing against 1 :)

VikingofRock
Aug 24, 2008




ExcessBLarg! posted:

Honestly trying to remember the last time I wanted to know when some floating point value == 1.0 exactly. I can't think of one.

Maybe you are dividing by the logarithm of the number?

Dr. Stab
Sep 12, 2010
👨🏻‍⚕️🩺🔪🙀😱🙀

VikingofRock posted:

Maybe you are dividing by the logarithm of the number?

That certainly sounds like a situation where you'd want to use a tolerance.

VikingofRock
Aug 24, 2008




Dr. Stab posted:

That certainly sounds like a situation where you'd want to use a tolerance.

Maybe you have a case where large numbers are acceptable, but Infinite numbers are not?

Series DD Funding
Nov 25, 2014

by exmarx

Dylan16807 posted:

Integer overflow is not simple either. Do it in C and the program can make up whatever number it wants, or return halfway through the function, or crash.

Only if it's a signed integer

sarehu
Apr 20, 2007

(call/cc call/cc)

Dr. Stab posted:

That certainly sounds like a situation where you'd want to use a tolerance.

Okay, fabs(x - 1.0) <= pow(2,-54). There's your tolerance.

Absurd Alhazred
Mar 27, 2010

by Athanatos
C++ code:
if (foo == null)
{
	foo == bar();
}

/* ... */

baz = blorax(*foo); // blorax(footype& f);
:doh:

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

Absurd Alhazred posted:

C++ code:
if (foo == null)
{
	foo == bar();
}

/* ... */

baz = blorax(*foo); // blorax(footype& f);
:doh:

Maybe my addled brain is missing something, but isn't this safe? You ensure foo is non-null before you dereference it. That's what you should do.

The real horror is that you forgot that quux comes after baz. :colbert:

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
It doesn't actually ensure foo is non-null.

xzzy
Mar 5, 2009

I've never made it to quux.

Though I do have a "biz" into my lovely variable sequence: foo bar biz baz. Googling it it looks like biz doesn't actually exist as part of the pattern and I should have been using quux all these years.

Truly a coding horror.

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe

Plorkyeran posted:

It doesn't actually ensure foo is non-null.

Oh, missed the second "=". :doh: indeed.

I was going to suggest that maybe the compiler should warn you when your code contains a useless statement, but I guess you could have overloaded operator== to have side effects!

hobbesmaster
Jan 28, 2008

Absurd Alhazred posted:

C++ code:
if (foo == null)
{
	foo == bar();
}

/* ... */

baz = blorax(*foo); // blorax(footype& f);
:doh:

Most compilers seem to have this warning off by default (e.g. for vc++ C4555 expression has no effect; expected expression with side-effect). Why is this one off by default but they whine a ton about unused arguments.

Absurd Alhazred
Mar 27, 2010

by Athanatos

xzzy posted:

I've never made it to quux.

Though I do have a "biz" into my lovely variable sequence: foo bar biz baz. Googling it it looks like biz doesn't actually exist as part of the pattern and I should have been using quux all these years.

Truly a coding horror.

Live a little. Use blorax.

TooMuchAbstraction posted:

Oh, missed the second "=". :doh: indeed.

I was going to suggest that maybe the compiler should warn you when your code contains a useless statement, but I guess you could have overloaded operator== to have side effects!

It's a longtime annoyance of mine with C and derivatives, that they allow return values to just lie there in code, and that = and == look too similar. This is the first time ever this has happened to me in this direction, though. What usually gets me is if (something = awful). :v:

fritz
Jul 26, 2003

Absurd Alhazred posted:

It's a longtime annoyance of mine with C and derivatives, that they allow return values to just lie there in code,

printf returns a value.

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"

fritz posted:

printf returns a value.

code:
_ = printf("butts = %f\n", x);
Doesn't seem so bad.

b0lt
Apr 29, 2005

Absurd Alhazred posted:

It's a longtime annoyance of mine with C and derivatives, that they allow return values to just lie there in code

__attribute__((warn_unused_result))

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer

Absurd Alhazred posted:

Live a little. Use blorax.

At that point I'd prefer tlön uqbar orbis tertius.

xtal
Jan 9, 2011

by Fluffdaddy

Absurd Alhazred posted:

It's a longtime annoyance of mine with C and derivatives, that they allow return values to just lie there in code

By return value do you mean expression? Because that makes perfect sense

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



XML code:
<endpoint blah="blah" what="ever" contract=" Type.Name.Here" />
The horror is that that's not a runtime error

The places where .Net just becomes agnostic to things not existing are always surprising in the dumbest loving ways.

Coffee Mugshot
Jun 26, 2010

by Lowtax

Absurd Alhazred posted:

It's a longtime annoyance of mine with C and derivatives, that they allow return values to just lie there in code, and that = and == look too similar. This is the first time ever this has happened to me in this direction, though. What usually gets me is if (something = awful). :v:

Which language doesn't allow you to write
code:
true
?

Adbot
ADBOT LOVES YOU

SupSuper
Apr 8, 2009

At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it.

Munkeymon posted:

XML code:
<endpoint blah="blah" what="ever" contract=" Type.Name.Here" />
The horror is that that's not a runtime error

The places where .Net just becomes agnostic to things not existing are always surprising in the dumbest loving ways.
You can set throwOnError=true, but yeah the fact it isn't the default has caught me off-guard a few times.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply