Closed CeylonMigrationBot closed 8 years ago
[@lucaswerkmeister]
Does anyone happen to have a copy of the IEEE spec?
I can get access via my university account. Does Wikipedia refer to a specific section?
[@lucaswerkmeister] Found it. 9.2.1 Special values, pp. 43–45.
For the pow function […] pow(x, ±0) is 1 for any x (even a zero, quiet NaN, or infinity) […] pow(+1,y) is 1 for any y (even a quiet NaN)
[@lucaswerkmeister] Note, however, that the standard also defines pown and powr. The descriptions are:
[…] the pown function (integral exponents only) […] […] the pow function (integral exponents get special treatment) […] […] the powr function (derived by considering only exp(y×log(x))) […]
[@lucaswerkmeister] And:
powr(±0, ±0) signals the invalid operation exception powr(+∞, ±0) signals the invalid operation exception powr(+1, ±∞) signals the invalid operation exception
[@lucaswerkmeister] So perhaps Java’s and ECMAScript’s pow
is based on IEEE’s powr
, replacing “invalid operation exception” with NaN.
[@jvasileff] It looks like the IEEE spec for this was released in 2008 (after java.lang.Math) - https://en.wikipedia.org/wiki/IEEE_754_revision. Of course, that doesn't tell us what they would have done.
[@lucaswerkmeister] That’s true… the original IEEE 754-1985 doesn’t define any operations beside
An implementation shall provide the add, subtract, multiply, divide, and remainder operation
and
The square root operation shall be provided.
[@gavinking] No, Java's pow()
isn't powr()
either. Look at powr(0,0)
and powr(infinity,0)
.
[@jvasileff] I think I'd go with IEEE, primarily because it seems like the least opinionated approach. But also, the rules look reasonable enough.
I thought pow(-1.0, ±∞) == 1
was strange at first, but with floats, you've already "lost" once y
is a large number, all of which are all even.
Edit: changed Dart API url; the old one stopped working
[@lucaswerkmeister] This is a mess. Examined languages:
Examined special cases:
pow(0.0, 0.0)
:
1.0
: Java, ECMAScript, C, Dart, Go, Python, IEEE pow
powr
pow(1.0, +∞)
:
NaN
: Java, ECMAScript1.0
: C, Dart, Go, Python, IEEE pow
powr
pow(1.5, +∞)
:
+∞
: Java, ECMAScript, C, Dart, Go, Pythonpow
, IEEE powr
My results:
pow
in all cases that the latter specifies. They also define some additional special cases that IEE 754-2008 pow
doesn’t specify; these extensions are the same across all these languages. (All rules that refer to the absolute value of the first argument are such additions.)pow
in most, but not all cases that the latter specifies. In the unspecified cases, they agree with the above languages.I think we should follow C, Dart, Go, Python.
[@gavinking]
@jvasileff well it does seem to me wrong that pow(-1.0, ∞) == 1.0
. I don't see where that comes from. pow(-1.0, n)
does not converge as n
approaches ∞
.
So I don't see where IEEE gets that from.
[@jvasileff]
@gavinking but we're taking about floats, where really big numbers at some point just become "infinity" (instead of triggering an overflow exception). And for big numbers, the answer is 1.0
, since in this fake-number-world, all big numbers are even.
So I think the interpretation is that infinity just means a number outside of the representable range (which surely must be an even integer!), and not a proper infinity in a mathematical sense.
Bottom line: folks shouldn't be doing this sort of calculation with floats, but to stop them entirely, we'd have to have pow(-1.0, *)
be undefined.
[@gavinking] @jvasileff That's not true. Really big negative numbers become -infinity
, not infinity
.
[@jvasileff] Sure, I was speaking in terms of magnitude.
[@gavinking] Oh, sorry, I misunderstood your argument. Yeah, OK, so with limited precision, all large floating point exponents are even. That's ... a very weird side-effect of limited-precision floating-point arithmetic.
[@FroMage] @gavinking: where's that Wikipedia page you talk about, I can't find it?
I can implement that for both JS and JVM, but I'd like to see some better specs, since it's pretty famous math is a foreign language to me.
For the pow function […] pow(x, ±0) is 1 for any x (even a zero, quiet NaN, or infinity) […] pow(+1,y) is 1 for any even y (even a quiet NaN)
@lucaswerkmeister this says infinity
but does not say positive/negative. Am I to conclude that it's for both infinities?
I thought
pow(-1.0, ±∞) == 1
was strange at first, but with floats, you've already "lost" once y is a large number, all of which are all even.
@jvasileff where did you find that? I can't find it in @gavinking's issue description, nor in the quoted IEEE spec in comments. Should I implement that too?
[@lucaswerkmeister] @FroMage pretty sure, yes, especially since it’s only a clarification for “any x”.
[@FroMage] OK fine.
[@jvasileff] @FroMage in the Dart and Go links here #5615#issuecomment-136228316 which claim to be consistent with IEEE Standard 754-2008.
[@FroMage] @jvasileff: Dart says:
pow(+1, y) is 1 for any y (even a quiet NaN)
But @lucaswerkmeister quoted IEEE as saying:
pow(+1,y) is 1 for any even y (even a quiet NaN)
Not sure what to make of that.
[@lucaswerkmeister] hang on, I might’ve misquoted
[@FroMage] aha :)
[@lucaswerkmeister] yup, sorry.
pow (+1, y ) is 1 for any y (even a quiet NaN)
[@lucaswerkmeister] and that’s why I don’t copy+paste out of that stupid document :D
[@lucaswerkmeister] fixed in my comment above
[@FroMage] OK thanks.
[@lucaswerkmeister] Lemme give y’all folks the spec so we can discuss on the same level :)
[@FroMage] I've updated the JS and JVM runtime to align us with what I believe is the IEEE spec. Please review. If you wish to deviate from the IEEE spec, at least now you can see where in the code it has to be done ;)
I won't close this until you guys come to an agreement, but I vote for following the IEEE spec.
[@lucaswerkmeister] @FroMage what’s pow(1.5, +∞)
now?
[@lucaswerkmeister] oh I see, that’s a test case. good
[@gavinking] The consensus seems to be to go with the IEEE definition of pow()
. Fine by me. I'll assume @FroMage's impl is good and close this issue.
[@gavinking] Wikipedia claims that the IEEE standard mandates that
pow(1.0, ∞)
evaluates to1.0
, along withpow(0.0, 0.0)
andpow(∞, 0.0)
, and that seems intuitively correct to me. I can see howpow(-1.0, ∞)
should be NaN, but that seems a pretty different case.However, Java's
Math.pow()
function apparently has its own idea andMath.pow(1.0, Math.POSITIVE_INFINITY)
evaluates to NaN, and if I', reading the ECMA spec right, it seems to specify the same thing.What should Ceylon do here?
Does anyone happen to have a copy of the IEEE spec?
Note also this comment in the Dart issue tracker.
[Migrated from ceylon/ceylon.language#737] [Closed at 2015-09-03 01:02:48]