Infinity

From Rosetta Code

Jump to: navigation, search

Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.

Code examples should be formatted along the lines of one of the existing prototypes.
Write a function which tests if infinity is supported for floating point numbers (this step should be omitted for languages where the language specification already demands the existence of infinity, e.g. by demanding IEEE numbers), and if so, returns positive infinity. Otherwise, return the largest possible number.

For languages with several floating point types, use the type of the literal constant 1.0 as floating point type.

Contents

[edit] Ada

 
with Ada.Text_IO; use Ada.Text_IO;
 
procedure Infinities is
   function Sup return Float is -- Only for predefined types
      Result : Float := Float'Last;
   begin
      if not Float'Machine_Overflows then
         Result := Float'Succ (Result);
      end if;
      return Result;
   end Sup;
 
   function Inf return Float is -- Only for predefined types
      Result : Float := Float'First;
   begin
      if not Float'Machine_Overflows then
         Result := Float'Pred (Result);
      end if;
      return Result;
   end Inf;
begin
   Put_Line ("Supremum" & Float'Image (Sup));
   Put_Line ("Infimum " & Float'Image (Inf));
end Infinities;
 

The language-defined attribute Machine_Overflows is defined for each floating-point type. It is true when an overflow or divide-by-zero results in Constraint_Error exception propagation. When the underlying machine type is incapable to implement this semantics the attribute is false. It is to expect that on the machines with IEEE 754 hardware Machine_Overflows is true. The language-defined attributes Succ and Pred yield the value next or previous to the argument, correspondingly.

Sample output on a machine where Float is IEEE 754:

Supremum +Inf*******
Infimum -Inf*******

Note that the code above does not work for user-defined types, which may have range of values narrower than one of the underlying hardware type. This case represents one of the reasons why Ada programmers are advised not to use predefined floating-point types. There is a danger that the implementation of might be IEEE 754, and so the program semantics could be broken.

Here is the code that should work for any type on any machine:

 
with Ada.Text_IO; use Ada.Text_IO;
 
procedure Infinities is
   type Real is digits 5 range -10.0..10.0;
 
   function Sup return Real is
      Result : Real := Real'Last;
   begin
      return Real'Succ (Result);
   exception
      when Constraint_Error =>
         return Result;
   end Sup;
 
   function Inf return Real is
      Result : Real := Real'First;
   begin
      return Real'Pred (Result);
   exception
      when Constraint_Error =>
         return Result;
   end Inf;
begin
   Put_Line ("Supremum" & Real'Image (Sup));
   Put_Line ("Infimum " & Real'Image (Inf));
end Infinities;
 

Sample output. Note that the compiler is required to generate Constraint_Error even if the hardware is IEEE 754. So the upper and lower bounds are 10.0 and -10.0:

Supremum 1.0000E+01
Infimum -1.0000E+01

[edit] C++

#include <limits>

double inf()
{
  if (std::numeric_limits<double>::has_infinity)
    return std::numeric_limits<double>::infinity();
  else
    return std::numeric_limits<double>::max();
}

[edit] D

typeof(1.0) inf()
{
  return typeof(1.0).infinity;
}

[edit] Fortran

ISO Fortran 2003 or later supports an IEEE_ARITHMETIC module which defines a wide range of intrinsic functions and types in support of IEEE floating point formats and arithmetic rules.

  program to_f_the_ineffable
     use, intrinsic :: ieee_arithmetic
     integer :: i
     real dimension(2) :: y, x = (/ 30, ieee_value(y,ieee_positive_inf) /)
     
     do i = 1, 2
        if (ieee_support_datatype(x(i))) then
           if (ieee_is_finite(x(i))) then
              print *, 'x(',i,') is finite'
           else
              print *, 'x(',i,') is infinite'
           end if
           
        else
           print *, 'x(',i,') is not in an IEEE-supported format'
        end if
     end do
  end program to_f_the_ineffable

ISO Fortran 90 or later supports a HUGE intrinsic which returns the largest value supported by the data type of the number given.

  real :: x
  real :: huge_real = huge(x)

[edit] Haskell

The Haskell 98 standard does not require full IEEE numbers, and the required operations on floating point numbers leave some degree of freedom to the implementation. Also, it's not possible to use the type of the literal 1.0 to decide which concrete type to use, because Haskell number literals are automatically converted.

Nevertheless, the following may come close to the task description:

maxRealFloat :: RealFloat a => a -> a
maxRealFloat x = encodeFloat b (e-1) `asTypeOf` x where
  b     = floatRadix x - 1
  (_,e) = floatRange x

infinity :: RealFloat a => a
infinity = if isInfinite inf then inf else maxRealFloat 1.0 where
  inf = 1/0 

Test for the two standard floating point types:

*Main> infinity :: Float
Infinity
*Main> infinity :: Double
Infinity

[edit] IDL

IDL provides the standard IEEE values for _inf and _NaN in the !Values system structure:

print, !Values.f_infinity             ;; for normal floats or
print, !Values.D_infinity             ;; for doubles  

[edit] J

Positive infinity is produced by the primary constant function _:
It is also represented directly as a numeric value by an underscore, used alone.

[edit] Io

inf := 1/0

[edit] Java

Java does not have a test for the existence of infinity, but it does have the concept in the Double class.

double infinity = Double.POSITIVE_INFINITY; //defined as 1.0/0.0
Double.isInfinite(infinity); //true

As a function:

public static double getInf(){
   return Double.POSITIVE_INFINITY;
}

The largest possible number in Java (without using the Big classes) is also in the Double class.

double biggestNumber = Double.MAX_VALUE;

Its value is (2-2-52)*21023 or 1.7976931348623157*10308 (a.k.a. "big"). Other number classes (Integer, Long, Float, Byte, and Short) have maximum values that can be accessed in the same way.

[edit] JavaScript

JavaScript has a special global property called "Infinity":

Infinity

as well as constants in the Number class:

Number.POSITIVE_INFINITY
Number.NEGATIVE_INFINITY

The global isFinite() function tests for finiteness:

isFinite(x)

[edit] OCaml

infinity

is already a pre-defined value in OCaml.

# infinity;;
- : float = infinity
# 1.0 /. 0.0;;
- : float = infinity

[edit] Perl

I'm don't know of the official way to get infinity. The following seems to work on my version of Perl:

1e600

Unfortunately, "1.0 / 0.0" doesn't evaluate to infinity; but throws an exception.

[edit] PHP

This is how you get infinity:

INF

Unfortunately, "1.0 / 0.0" doesn't evaluate to infinity; but instead seems to evaluate to False, which is more like 0 than infinity.

PHP has functions is_finite() and is_infinite() to test for infiniteness.

[edit] Python

This is how you get infinity:

>>> float('infinity')
inf

Note: When passing in a string to float(), values for NaN and Infinity may be returned, depending on the underlying C library. The specific set of strings accepted which cause these values to be returned depends entirely on the underlying C library used to compile Python itself, and is known to vary.
The Decimal module explicitly supports +/-infinity Nan, +/-0.0, etc without exception.


Floating-point division by 0 doesn't give you infinity, it raises an exception:

>>> 1.0 / 0.0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: float division

[edit] Ruby

Infinity = 1.0/0
Personal tools