note
	description: "Routines that ought to be in class DOUBLE"
	library: "Gobo Eiffel Kernel Library"
	copyright: "Copyright (c) 2003-2018, Eric Bezault and others"
	license: "MIT License"
	date: "$Date: 2019-02-07 22:54:15 +0000 (Thu, 07 Feb 2019) $"
	revision: "$Revision: 102807 $"

class 
	KL_DOUBLE_ROUTINES

inherit
	DOUBLE_MATH
		rename
			log as old_log,
			log10 as old_log10,
			exp as old_exp
		export
			{NONE} all
		end

	KL_SHARED_PLATFORM

create 
	default_create

feature -- Logarithms

	log (d: REAL_64): REAL_64
			-- Natural logarithm of d
		require
			d_positive: d > 0.0
		do
			Result := old_log (d)
		ensure
			instance_free: class
		end

	log2 (d: REAL_64): REAL_64
			-- Base 2 logarithm of d
		require
			d_positive: d > 0.0
		do
			Result := log_2 (d)
		ensure
			instance_free: class
		end

	log10 (d: REAL_64): REAL_64
			-- Base 10 logarithm of d
		require
			d_positive: d > 0.0
		do
			Result := old_log10 (d)
		ensure
			instance_free: class
		end
	
feature -- Exponent

	exp (d: REAL_64): REAL_64
			-- Inverse of the natural logarithm
		do
			Result := old_exp (d)
		ensure
			instance_free: class
		end

	nth_root (d, n: REAL_64): REAL_64
			-- n-th root of d
		require
			divisible: (1.0).divisible (n)
		do
			Result := d ^ (1.0 / n)
		ensure
			instance_free: class
		end
	
feature -- Conversion

	truncated_to_integer (d: REAL_64): INTEGER_32
			-- Integer part (Same sign, largest absolute
			-- value no greater than current object's)
		require
			d_large_enough: d >= Platform.Minimum_integer.to_double
			d_small_enough: d <= Platform.Maximum_integer.to_double
		do
			Result := d.truncated_to_integer
		ensure
			instance_free: class
		end

	rounded_to_integer (d: REAL_64): INTEGER_32
			-- Rounded integral value
		require
			d_large_enough: (d.abs + 0.5) >= Platform.Minimum_integer.to_double
			d_small_enough: (d.abs + 0.5) < (Platform.Maximum_integer.to_double + 1.0)
		do
			Result := d.rounded
		ensure
			instance_free: class
			definition: Result = d.sign * floor_to_integer (d.abs + 0.5)
		end

	floor_to_integer (d: REAL_64): INTEGER_32
			-- INTEGER floor
		require
			d_large_enough: d >= Platform.Minimum_integer.to_double
			d_small_enough: d < (Platform.Maximum_integer.to_double + 1.0)
		do
			Result := d.truncated_to_integer
			if d.floor /= Result then
				Result := Result - 1
			end
		ensure
			instance_free: class
			definition: Result = d.floor
		end
	
feature -- NaN

	is_nan (d: REAL_64): BOOLEAN
			-- Does d correspond to a Not-A-Number?
		local
			p1: MANAGED_POINTER
			b1, b2, b3, b4, b5, b6, b7, b8: NATURAL_8
		do
			if d /= d then
				Result := True
			else
				create p1.make (8)
				p1.put_real_64 (d, 0)
				b1 := p1.read_natural_8 (0)
				b2 := p1.read_natural_8 (1)
				b3 := p1.read_natural_8 (2)
				b4 := p1.read_natural_8 (3)
				b5 := p1.read_natural_8 (4)
				b6 := p1.read_natural_8 (5)
				b7 := p1.read_natural_8 (6)
				b8 := p1.read_natural_8 (7)
				if b8 = 127 or b8 = 255 then
					if b7 > 240 then
						Result := True
					elseif b7 = 240 then
						Result := b6 /= 0 or b5 /= 0 or b4 /= 0 or b3 /= 0 or b2 /= 0 or b1 /= 0
					end
				end
			end
		ensure
			instance_free: class
		end
	
feature -- Infinity

	is_plus_infinity (d: REAL_64): BOOLEAN
			-- Does d correspond to positive infinity?
		local
			p1, p2: MANAGED_POINTER
		do
			if d /= d then
				Result := False
			else
				create p1.make (8)
				p1.put_real_64 (d, 0)
				create p2.make (8)
				p2.put_real_64 (Plus_infinity, 0)
				Result := p1.read_natural_64 (0) = p2.read_natural_64 (0)
			end
		ensure
			instance_free: class
		end

	is_minus_infinity (d: REAL_64): BOOLEAN
			-- Does d correspond to minus infinity?
		local
			p1, p2: MANAGED_POINTER
		do
			if d /= d then
				Result := False
			else
				create p1.make (8)
				p1.put_real_64 (d, 0)
				create p2.make (8)
				p2.put_real_64 (Minus_infinity, 0)
				Result := p1.read_natural_64 (0) = p2.read_natural_64 (0)
			end
		ensure
			instance_free: class
		end

	Plus_infinity: REAL_64
			-- Positive infinity
		local
			p: MANAGED_POINTER
		once
			create p.make (8)
			p.put_natural_8 (0, 0)
			p.put_natural_8 (0, 1)
			p.put_natural_8 (0, 2)
			p.put_natural_8 (0, 3)
			p.put_natural_8 (0, 4)
			p.put_natural_8 (0, 5)
			p.put_natural_8 (240, 6)
			p.put_natural_8 (127, 7)
			Result := p.read_real_64 (0)
		ensure
			instance_free: class
			positive: Result > 0.to_double
		end

	Minus_infinity: REAL_64
			-- Negative infinity
		local
			p: MANAGED_POINTER
		once
			create p.make (8)
			p.put_natural_8 (0, 0)
			p.put_natural_8 (0, 1)
			p.put_natural_8 (0, 2)
			p.put_natural_8 (0, 3)
			p.put_natural_8 (0, 4)
			p.put_natural_8 (0, 5)
			p.put_natural_8 (240, 6)
			p.put_natural_8 (255, 7)
			Result := p.read_real_64 (0)
		ensure
			instance_free: class
			negative: Result < 0.to_double
		end
	
end -- class KL_DOUBLE_ROUTINES

Generated by ISE EiffelStudio