As soon as I get my head out of the Ukraine conflict,
and start doing Prolog, my sixth sense of stepping into
corner cases starts working again. Eh voilà while doing
some regression testing I found:
/* Math, -0.6662760212798241 */
cos(2.3) = 0xbfe5522217302fe1
Versus:
/* StrictMath, -0.666276021279824 */
cos(2.3) = 0xbfe5522217302fe0
There are some Prolog systems which side with Math and not with
StrictMath. For example Scryer Prolog and ECLiPSe Prolog. But then
some side with StrictMath like Tau Prolog, Dogelog and GNU Prolog.
Is there maybe a flag where the strictness can be queried or controlled?
I can produce the different two return values in Java JDK 16
Windows 10, by either using the Java class StrictMath or Math.
Now I found that such a discrepancy also exists across Prolog
systems. Math is characterized as:
Unlike some of the numeric methods of class StrictMath , all
implementations of the equivalent functions of class Math are
not defined to return the bit-for-bit same results. This relaxation
permits better-performing implementations where strict
reproducibility is not required. https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/Math.html
Mostowski Collapse schrieb am Montag, 21. März 2022 um 09:26:59 UTC+1:
As soon as I get my head out of the Ukraine conflict,
and start doing Prolog, my sixth sense of stepping into
corner cases starts working again. Eh voilà while doing
some regression testing I found:
/* Math, -0.6662760212798241 */
cos(2.3) = 0xbfe5522217302fe1
Versus:
/* StrictMath, -0.666276021279824 */
cos(2.3) = 0xbfe5522217302fe0
There are some Prolog systems which side with Math and not with StrictMath. For example Scryer Prolog and ECLiPSe Prolog. But then
some side with StrictMath like Tau Prolog, Dogelog and GNU Prolog.
I don’t know what Dodgelog should be, I only know about Dogelog.
But on 64-bit Intel, the Math cos() is simply these op-codes:
0xD9 0xFF
http://ref.x86asm.net/coder64.html
That is what JDK 16 in Math mode seems to use. According to
JDK-8143353 the performance gain is ~4.25x with both sin and cos.
https://bugs.openjdk.java.net/browse/JDK-8143353
But I did not yet do some performance measures. Also I did not
verify first hand by myself that this opcode really gives the different value.
Mostowski Collapse schrieb am Montag, 21. März 2022 um 09:28:40 UTC+1:
Is there maybe a flag where the strictness can be queried or controlled?
I can produce the different two return values in Java JDK 16
Windows 10, by either using the Java class StrictMath or Math.
Now I found that such a discrepancy also exists across Prolog
systems. Math is characterized as:
Unlike some of the numeric methods of class StrictMath , all implementations of the equivalent functions of class Math are
not defined to return the bit-for-bit same results. This relaxation permits better-performing implementations where strict
reproducibility is not required. https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/Math.html
Mostowski Collapse schrieb am Montag, 21. März 2022 um 09:26:59 UTC+1:
As soon as I get my head out of the Ukraine conflict,
and start doing Prolog, my sixth sense of stepping into
corner cases starts working again. Eh voilà while doing
some regression testing I found:
/* Math, -0.6662760212798241 */
cos(2.3) = 0xbfe5522217302fe1
Versus:
/* StrictMath, -0.666276021279824 */
cos(2.3) = 0xbfe5522217302fe0
There are some Prolog systems which side with Math and not with StrictMath. For example Scryer Prolog and ECLiPSe Prolog. But then
some side with StrictMath like Tau Prolog, Dogelog and GNU Prolog.
So what is the correct value? Interestingly its not from StrictMath:
In Jekejeke Prolog we use (d < 0 ? -Math.round(-d) : Math.round(d)).
This is done to be compatible with SWI-Prolog.
Interestingly, ECLiPSe Prolog does this border cases like Python,
and Tau Prolog does it like JavaScript.
Where is Logtalk with its many test cases, shouldn't
by now all Prolog systems behave the same thanks
to the enduring path of glory of Logtalk? LoL
Mostowski Collapse schrieb am Mittwoch, 23. März 2022 um 23:03:57 UTC+1:
Somebody brought round() on the table on SWI-Prolog discourse.
Now I am baffled, I get:
/* Formerly Jekejeke, a little Math.round() */
?- X is 0.5, Y is round(X).
X = 0.5, Y = 1.0.
?- X is -0.5, Y is round(X).
X = -0.5, Y = -1.0.
?- X is 1.5, Y is round(X).
X = 1.5, Y = 2.0.
?- X is -1.5, Y is round(X).
X = -1.5, Y = -2.0.
/* Dogelog JavaScript */
?- X is 0.5, Y is round(X).
X = 0.5, Y = 1.0.
?- X is -0.5, Y is round(X).
X = -0.5, Y = 0.0.
?- X is 1.5, Y is round(X).
X = 1.5, Y = 2.0.
?- X is -1.5, Y is round(X).
X = -1.5, Y = -1.0.
/* Dogelog Python */
?- X is 0.5, Y is round(X).
X = 0.5, Y = 0.0.
?- X is -0.5, Y is round(X).
X = -0.5, Y = 0.0.
?- X is 1.5, Y is round(X).
X = 1.5, Y = 2.0.
?- X is -1.5, Y is round(X).
X = -1.5, Y = -2.0.
The JavaScript thingy can easily be fixed, but the Python thingy?
LoL
Mostowski Collapse schrieb am Dienstag, 22. März 2022 um 08:21:12 UTC+1:
So what is the correct value? Interestingly its not from StrictMath:
Somebody brought round() on the table on SWI-Prolog discourse.
Now I am baffled, I get:
/* Formerly Jekejeke, a little Math.round() */
?- X is 0.5, Y is round(X).
X = 0.5, Y = 1.0.
?- X is -0.5, Y is round(X).
X = -0.5, Y = -1.0.
?- X is 1.5, Y is round(X).
X = 1.5, Y = 2.0.
?- X is -1.5, Y is round(X).
X = -1.5, Y = -2.0.
/* Dogelog JavaScript */
?- X is 0.5, Y is round(X).
X = 0.5, Y = 1.0.
?- X is -0.5, Y is round(X).
X = -0.5, Y = 0.0.
?- X is 1.5, Y is round(X).
X = 1.5, Y = 2.0.
?- X is -1.5, Y is round(X).
X = -1.5, Y = -1.0.
/* Dogelog Python */
?- X is 0.5, Y is round(X).
X = 0.5, Y = 0.0.
?- X is -0.5, Y is round(X).
X = -0.5, Y = 0.0.
?- X is 1.5, Y is round(X).
X = 1.5, Y = 2.0.
?- X is -1.5, Y is round(X).
X = -1.5, Y = -2.0.
The JavaScript thingy can easily be fixed, but the Python thingy?
LoL
Mostowski Collapse schrieb am Dienstag, 22. März 2022 um 08:21:12 UTC+1:
So what is the correct value? Interestingly its not from StrictMath:
Because the test is from here:
real(1.0e+32).
test(lgt_unbounded_round_01, true(integer(N))) :-
real(Value),
N is round(Value). https://github.com/LogtalkDotOrg/logtalk3/blob/master/tests/prolog/unbounded/tests.lgt
But the test doesn't make any sense obviously,
only testing whether a result is integer, and not what
it is particularly.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:41:32 UTC+1:
Ha Ha, Logtalk Nonsense is as real as a Pink Unicorn.
If they would really have all these adapters and their
test suite, they would have by long already detected this bug:
round() result #1365
https://github.com/mthom/scryer-prolog/issues/1365
LoL
But round is really a can of worms. Just out of curiousity I was
checking out the ISO core standard, and it tells me:
round(x) = floor(x+1/2)
For example my definition of round function usually says,
and what SWI-Prolog possibly implemented so far:
round(x) = truncate(x + sign(x)*1/2)
And not what the ISO core standard gives.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:44:06 UTC+1:
Because the test is from here:
real(1.0e+32).
test(lgt_unbounded_round_01, true(integer(N))) :-
real(Value),
N is round(Value). https://github.com/LogtalkDotOrg/logtalk3/blob/master/tests/prolog/unbounded/tests.lgt
But the test doesn't make any sense obviously,
only testing whether a result is integer, and not what
it is particularly.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:41:32 UTC+1:
Ha Ha, Logtalk Nonsense is as real as a Pink Unicorn.
If they would really have all these adapters and their
test suite, they would have by long already detected this bug:
round() result #1365
https://github.com/mthom/scryer-prolog/issues/1365
LoL
Ha Ha, Logtalk Nonsense is as real as a Pink Unicorn.
If they would really have all these adapters and their
test suite, they would have by long already detected this bug:
round() result #1365
https://github.com/mthom/scryer-prolog/issues/1365
LoL
Does it make a difference. Well you can check yourself:
So I made some additional tests, first Scryer Prolog v0.8.123:
?- X is round(0.5).
X = 1.
?- X is round(-0.5).
X = 0.
And then SWI-Prolog 8.5.8:
?- X is round(0.5).
X = 1.
?- X is round(-0.5).
X = -1.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:45:21 UTC+1:
But round is really a can of worms. Just out of curiousity I was
checking out the ISO core standard, and it tells me:
round(x) = floor(x+1/2)
For example my definition of round function usually says,
and what SWI-Prolog possibly implemented so far:
round(x) = truncate(x + sign(x)*1/2)
And not what the ISO core standard gives.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:44:06 UTC+1:
Because the test is from here:
real(1.0e+32).
test(lgt_unbounded_round_01, true(integer(N))) :-
real(Value),
N is round(Value). https://github.com/LogtalkDotOrg/logtalk3/blob/master/tests/prolog/unbounded/tests.lgt
But the test doesn't make any sense obviously,
only testing whether a result is integer, and not what
it is particularly.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:41:32 UTC+1:
Ha Ha, Logtalk Nonsense is as real as a Pink Unicorn.
If they would really have all these adapters and their
test suite, they would have by long already detected this bug:
round() result #1365 https://github.com/mthom/scryer-prolog/issues/1365
LoL
Thats quite an amazing scale of failure by Logtalk Nonsense,
given the fact that it promoted QuickCheck. Almost as cring
as the failed Invasion of Ukraine by Russia. Unfortunately
Europe gets now fucked up by US via NATO?
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:48:12 UTC+1:
Does it make a difference. Well you can check yourself:
So I made some additional tests, first Scryer Prolog v0.8.123:
?- X is round(0.5).
X = 1.
?- X is round(-0.5).
X = 0.
And then SWI-Prolog 8.5.8:
?- X is round(0.5).
X = 1.
?- X is round(-0.5).
X = -1.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:45:21 UTC+1:
But round is really a can of worms. Just out of curiousity I was checking out the ISO core standard, and it tells me:
round(x) = floor(x+1/2)
For example my definition of round function usually says,
and what SWI-Prolog possibly implemented so far:
round(x) = truncate(x + sign(x)*1/2)
And not what the ISO core standard gives.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:44:06 UTC+1:
Because the test is from here:
real(1.0e+32).
test(lgt_unbounded_round_01, true(integer(N))) :-
real(Value),
N is round(Value). https://github.com/LogtalkDotOrg/logtalk3/blob/master/tests/prolog/unbounded/tests.lgt
But the test doesn't make any sense obviously,
only testing whether a result is integer, and not what
it is particularly.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:41:32 UTC+1:
Ha Ha, Logtalk Nonsense is as real as a Pink Unicorn.
If they would really have all these adapters and their
test suite, they would have by long already detected this bug:
round() result #1365 https://github.com/mthom/scryer-prolog/issues/1365
LoL
I wonder whether the existing flag iso could be used for
such purpose.
iso (bool, changeable)
https://www.swi-prolog.org/pldoc/man?section=flags
Currently it doesn’t have some effect on arithmetic.
What could go wrong?
It would then also have the semantic of some StrictMath,
not in the Java sense, but in the ISO core standard
sense. Or maybe there are other flags?
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 12:01:38 UTC+1:
Thats quite an amazing scale of failure by Logtalk Nonsense,
given the fact that it promoted QuickCheck. Almost as cring
as the failed Invasion of Ukraine by Russia. Unfortunately
Europe gets now fucked up by US via NATO?
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:48:12 UTC+1:
Does it make a difference. Well you can check yourself:
So I made some additional tests, first Scryer Prolog v0.8.123:
?- X is round(0.5).
X = 1.
?- X is round(-0.5).
X = 0.
And then SWI-Prolog 8.5.8:
?- X is round(0.5).
X = 1.
?- X is round(-0.5).
X = -1.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:45:21 UTC+1:
But round is really a can of worms. Just out of curiousity I was checking out the ISO core standard, and it tells me:
round(x) = floor(x+1/2)
For example my definition of round function usually says,
and what SWI-Prolog possibly implemented so far:
round(x) = truncate(x + sign(x)*1/2)
And not what the ISO core standard gives.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:44:06 UTC+1:
Because the test is from here:
real(1.0e+32).
test(lgt_unbounded_round_01, true(integer(N))) :-
real(Value),
N is round(Value). https://github.com/LogtalkDotOrg/logtalk3/blob/master/tests/prolog/unbounded/tests.lgt
But the test doesn't make any sense obviously,
only testing whether a result is integer, and not what
it is particularly.
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 11:41:32 UTC+1:
Ha Ha, Logtalk Nonsense is as real as a Pink Unicorn.
If they would really have all these adapters and their
test suite, they would have by long already detected this bug:
round() result #1365 https://github.com/mthom/scryer-prolog/issues/1365
LoL
Now I found some useless information, I don’t know yet what to do with. Java provides also the Python semantics via:
/**
* Returns the {@code double} value that is closest in value
* to the argument and is equal to a mathematical integer. If two
* {@code double} values that are mathematical integers are
* equally close to the value of the argument, the result is the
* integer value that is even.
*/
public static double rint(double a);
What I would be more interested is whether Python has a differerent
more Prolog like semantics round(). On the other hand the above piece of information might be not that useless. A Prolog system could provide
two rounding functions. An evaluable function round/1 à la ISO core standard, or some Prolog system specific divertimento like in SWI-Prolog, rint/1 with the Python semantics. Both available in a Prolog system?
As soon as I get my head out of the Ukraine conflict,
and start doing Prolog, my sixth sense of stepping into
corner cases starts working again. Eh voilà while doing
But now I am confused, I recently made the step to JDK 16. And now
I read “As of Java 17, using this keyword has no effect.” Does extended precision not anymore exist, is basically dead?
It seems to be dead, since taking a time machine, back then, 80-bit
was cheap (because there was FPU) and 64-bit was expensive, and
now its not anymore the case (because on chip).
At least when I read here JEP 306 it seems so. https://openjdk.java.net/jeps/306
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 20:58:39 UTC+1:
But the scope of StrictMath versus Math is usually only rounding functions, trigonometry functions exponential functions i.e. round/2, cos/2, exp/2, etc…
For control of arithmetic Java has the strictfp modifier, which would affect (-)/2, (+)/3, (*)/3, etc… I guess, and might affect whether 64-bit can be temporarily turned in 80-bit floats:
Extended precision
Extended precision formats support a basic format by minimizing
roundoff and overflow errors in intermediate values of expressions
on the base format
https://en.wikipedia.org/wiki/Extended_precision
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 20:33:07 UTC+1:
Now I found some useless information, I don’t know yet what to do with.
Java provides also the Python semantics via:
/**
* Returns the {@code double} value that is closest in value
* to the argument and is equal to a mathematical integer. If two
* {@code double} values that are mathematical integers are
* equally close to the value of the argument, the result is the
* integer value that is even.
*/
public static double rint(double a);
What I would be more interested is whether Python has a differerent
more Prolog like semantics round(). On the other hand the above piece of information might be not that useless. A Prolog system could provide
two rounding functions. An evaluable function round/1 à la ISO core standard, or some Prolog system specific divertimento like in SWI-Prolog,
rint/1 with the Python semantics. Both available in a Prolog system?
But the scope of StrictMath versus Math is usually only rounding
functions, trigonometry functions exponential functions i.e. round/2,
cos/2, exp/2, etc…
For control of arithmetic Java has the strictfp modifier, which would
affect (-)/2, (+)/3, (*)/3, etc… I guess, and might affect whether
64-bit can be temporarily turned in 80-bit floats:
Extended precision
Extended precision formats support a basic format by minimizing
roundoff and overflow errors in intermediate values of expressions
on the base format
https://en.wikipedia.org/wiki/Extended_precision
Mostowski Collapse schrieb am Donnerstag, 24. März 2022 um 20:33:07 UTC+1:
Now I found some useless information, I don’t know yet what to do with. Java provides also the Python semantics via:
/**
* Returns the {@code double} value that is closest in value
* to the argument and is equal to a mathematical integer. If two
* {@code double} values that are mathematical integers are
* equally close to the value of the argument, the result is the
* integer value that is even.
*/
public static double rint(double a);
What I would be more interested is whether Python has a differerent
more Prolog like semantics round(). On the other hand the above piece of information might be not that useless. A Prolog system could provide
two rounding functions. An evaluable function round/1 à la ISO core standard, or some Prolog system specific divertimento like in SWI-Prolog, rint/1 with the Python semantics. Both available in a Prolog system?
Now I wonder whether I can implement my own
round/1 evaluable function in a platform that doesn't
provide the round/1 that I want to have.
Example of such a platform would be Python.
Python rather provides Math.rint() instead of
Math.round(). So can we implement round/1 on
our own. It seems so, when we have suitable
float parts. Looking at SWI-Prolog:
?- float_parts(0.4, M, _, E).
M = 0.8,
E = -1.
I think the above doesn't work. It returns the mantissa
as a float, so we would be running in circles.
Whats more promissing is this take from our
own Prolog system, formerly Jekejeke Prolog:
?- sys_float_mantissa(0.4, M).
M = 7205759403792794.
?- sys_float_exponent(0.4, E).
E = -54.
Now we can define our own round/1 evaluable function, inspired
how Math.round() from Java does it. This shows only the sunshine
case for round/1, when E and M are in a suitable range:
round2(X,Y) :-
sys_float_mantissa(X, M),
sys_float_exponent(X, E),
Y is ((M >> (-E-1)) + 1) >> 1.
?- round2(23.4, X).
X = 23.
?- round2(24.6, X).
X = 25.
And for the nextto numbers:
?- 0.49999999999999994 == 0.4999999999999999.
fail.
?- round2(0.49999999999999994, X).
X = 0.
?- round2(0.4999999999999999, X).
X = 0.
Mostowski Collapse schrieb am Sonntag, 27. März 2022 um 16:06:59 UTC+2:
Now I wonder whether I can implement my own
round/1 evaluable function in a platform that doesn't
provide the round/1 that I want to have.
Example of such a platform would be Python.
Python rather provides Math.rint() instead of
Math.round(). So can we implement round/1 on
our own. It seems so, when we have suitable
float parts. Looking at SWI-Prolog:
?- float_parts(0.4, M, _, E).
M = 0.8,
E = -1.
I think the above doesn't work. It returns the mantissa
as a float, so we would be running in circles.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 430 |
Nodes: | 16 (2 / 14) |
Uptime: | 128:18:59 |
Calls: | 9,060 |
Calls today: | 7 |
Files: | 13,399 |
Messages: | 6,017,759 |
Posted today: | 1 |