Extreme floating point values: Difference between revisions
(Added Java) |
(Ada solution added) |
||
Line 8: | Line 8: | ||
* [[Infinity]] |
* [[Infinity]] |
||
* [[Detect division by zero]] |
* [[Detect division by zero]] |
||
=={{header|Ada}}== |
|||
The language specifies model floating-point numbers independent on the underlying hardware. In particular, even if the machine numbers are IEEE 754, the user-defined floating-point numbers are guaranteed to have no IEEE 754 semantics. In particular, their value do not include any non-numeric ideals. Constraint_Error exception is propagated when the result of a numeric operation assigned to a floating-point variable is not in the range (the range is always '''numeric'''). |
|||
For performance reasons, the built-in floating-point types like Float and Long_Float are allowed to have IEEE 754 semantics if the machine numbers are IEEE 754. But the language provides means to exclude all non numbers for these types by defining a subtype with an explicit range: |
|||
<lang Ada> |
|||
subtype Consistent_Float is Float range Float'Range; -- No IEEE ideals |
|||
</lang> |
|||
In general in properly written Ada programs variables may not become invalid when standard numeric operations are applied. The language also provides the attribute 'Valid to verify values obtained from input, unchecked conversions etc. |
|||
As stated above on a machine where Float is implemented by an IEEE 754 machine number, IEEE 754 is permitted leak through. The following program illustrates how this leak can be exploited: |
|||
<lang Ada> |
|||
with Ada.Text_IO; use Ada.Text_IO; |
|||
procedure IEEE is -- Non portable, bad, never do this! |
|||
Zero : Float := 0.0; |
|||
begin |
|||
Put_Line ("-oo = " & Float'Image (-1.0 / Zero)); |
|||
Put_Line ("+oo = " & Float'Image (1.0 / Zero)); |
|||
Put_Line ("NaN = " & Float'Image (0.0 / Zero)); |
|||
Put_Line (" -0 = " & Float'Image (1.0 / (-1.0 / Zero))); |
|||
end IEEE; |
|||
</lang> |
|||
The expression -1.0 / 0.0 were non-numeric and thus could not be used. To fool the compiler the variable Zero is used, which circumvents type checks giving desired broken result. Sample output: |
|||
<pre> |
|||
-oo = -Inf******* |
|||
+oo = +Inf******* |
|||
NaN = NaN******** |
|||
-0 = -0.00000E+00 |
|||
</pre> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
<lang java>public class Extreme { |
<lang java>public class Extreme { |
||
Line 33: | Line 62: | ||
0 * NaN: NaN |
0 * NaN: NaN |
||
Nan == NaN: false</pre> |
Nan == NaN: false</pre> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
<lang python>>>> # Extreme values from expressions |
<lang python>>>> # Extreme values from expressions |
Revision as of 21:28, 15 July 2010
The IEEE floating point specification defines certain 'extreme' floating point values such as minus zero, -0.0, a value distinct from plus zero; not a number, NaN; and plus and minus infinity.
The task is to use expressions involving other 'normal' floating point values in your language to calculate these, (and maybe other), extreme floating point values in your language and assign them to variables. Print the values of these variables if possible; and show some arithmetic with these values and variables. If your language can directly enter these extreme floating point values then show it.
C.f:
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- Infinity
- Detect division by zero
Ada
The language specifies model floating-point numbers independent on the underlying hardware. In particular, even if the machine numbers are IEEE 754, the user-defined floating-point numbers are guaranteed to have no IEEE 754 semantics. In particular, their value do not include any non-numeric ideals. Constraint_Error exception is propagated when the result of a numeric operation assigned to a floating-point variable is not in the range (the range is always numeric).
For performance reasons, the built-in floating-point types like Float and Long_Float are allowed to have IEEE 754 semantics if the machine numbers are IEEE 754. But the language provides means to exclude all non numbers for these types by defining a subtype with an explicit range: <lang Ada> subtype Consistent_Float is Float range Float'Range; -- No IEEE ideals </lang> In general in properly written Ada programs variables may not become invalid when standard numeric operations are applied. The language also provides the attribute 'Valid to verify values obtained from input, unchecked conversions etc.
As stated above on a machine where Float is implemented by an IEEE 754 machine number, IEEE 754 is permitted leak through. The following program illustrates how this leak can be exploited: <lang Ada> with Ada.Text_IO; use Ada.Text_IO;
procedure IEEE is -- Non portable, bad, never do this!
Zero : Float := 0.0;
begin
Put_Line ("-oo = " & Float'Image (-1.0 / Zero)); Put_Line ("+oo = " & Float'Image (1.0 / Zero)); Put_Line ("NaN = " & Float'Image (0.0 / Zero)); Put_Line (" -0 = " & Float'Image (1.0 / (-1.0 / Zero)));
end IEEE; </lang> The expression -1.0 / 0.0 were non-numeric and thus could not be used. To fool the compiler the variable Zero is used, which circumvents type checks giving desired broken result. Sample output:
-oo = -Inf******* +oo = +Inf******* NaN = NaN******** -0 = -0.00000E+00
Java
<lang java>public class Extreme {
public static void main(String[] args) { double negInf = -1.0 / 0.0; //also Double.NEGATIVE_INFINITY double inf = 1.0 / 0.0; //also Double.POSITIVE_INFINITY double nan = 0.0 / 0.0; //also Double.NaN double negZero = -2.0 / inf;
System.out.println("Negative inf: " + negInf); System.out.println("Positive inf: " + inf); System.out.println("NaN: " + nan); System.out.println("Negative 0: " + negZero); System.out.println("inf + -inf: " + (inf + negInf)); System.out.println("0 * NaN: " + (0 * nan)); System.out.println("Nan == NaN: " + (nan == nan)); }
}</lang> Output:
Negative inf: -Infinity Positive inf: Infinity NaN: NaN Negative 0: -0.0 inf + -inf: NaN 0 * NaN: NaN Nan == NaN: false
Python
<lang python>>>> # Extreme values from expressions >>> inf = 1e234 * 1e234 >>> _inf = 1e234 * -1e234 >>> _zero = 1 / _inf >>> nan = inf + _inf >>> inf, _inf, _zero, nan (inf, -inf, -0.0, nan) >>> # Print >>> for value in (inf, _inf, _zero, nan): print (value)
inf -inf -0.0 nan >>> # Extreme values from other means >>> float('nan') nan >>> float('inf') inf >>> float('-inf') -inf >>> -0. -0.0 >>> # Some arithmetic >>> nan == nan False >>> inf + _inf nan >>> 0.0 * nan nan >>> nan * 0.0 nan >>> 0.0 * inf nan >>> inf * 0.0 nan</lang>
<lang python>>>> # But note! >>> 1 / -0.0
Traceback (most recent call last):
File "<pyshell#106>", line 1, in <module> 1 / -0.0
ZeroDivisionError: float division by zero >>> # (Not minus infinity)</lang>