ssj@castle.ed.ac.uk (S Johal) (01/11/90)
Hello ADA experts, One of my colleagues has a problem which I hope somebody has an easy solution to. Basically he is after the whole number part of a floating point number. We found no way in ADA to directly implement it, so we tried something like: ROUNDED := INTEGER(FLOATING_NUMBER); if FLOATING_NUMBER - ROUNDED >= 0.0 then TRUNCATED_PART := ROUNDED; else TRUNCATED_PART := ROUNDED - 1; end if; examples: FLOATING_NUMBER ROUNDED TRUNCATED_PART 6.4 6 6 6.6 7 6 the problem is: 7.0 7 6 ??? when it should be 7 We have checked what 7.0 - 7.0 gives, and its not 0.0, which is the problem I suppose. My colleague knows about converting to a string and taking off the integer bit, but this is inefficient. Any ideas ? *-------------------------------------------*----------------------------* * Subindrao Johal, *++++++++++++++++++++++++++++* * SARI Project, * tel: 031 668 1550 x219 * * Department of Electrical Engineering, * fax: 031 662 4678 * * University of Edinburgh, * email: ssj@sari.ed.ac.uk * * The King's Buildings, Edinburgh EH9 3JL *++++++++++++++++++++++++++++* *------------------------------------------------------------------------*
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (01/11/90)
From ssj@castle.ed.ac.uk (S Johal): > [Trying to get the integer part of a floating point number:] > if FLOATING_NUMBER - ROUNDED >= 0.0 then > TRUNCATED_PART := ROUNDED; > else > TRUNCATED_PART := ROUNDED - 1; > end if; First, I currently handle it as follows: generic type FLOAT_TYPE is digits <>; type INTEGER_TYPE is range <>; function TRUNCATE (THE_FLOAT : in FLOAT_TYPE) return INTEGER_TYPE; -- Results may vary for values which are FLOAT_TYPE'EPSILON -- less than a whole number, depending on the compiler. It -- makes use of the compiler's integer-to-real conversion -- function, the semantics of which, at the point halfway -- between two whole numbers, is defined to be -- compiler-dependent (Ada 83 LRM 4.6 (7)). function TRUNCATE (THE_FLOAT : in FLOAT_TYPE) return INTEGER_TYPE is begin -- function TRUNCATE return INTEGER_TYPE (THE_FLOAT - (0.5 - FLOAT_TYPE'EPSILON)); -- works correctly @ boundary iff rounding is down... -- Another option is: -- return ( INTEGER_TYPE'(10.0 * THE_FLOAT) / 10 ); -- which eliminates the rounding error by truncating it away, -- but there are numeric overflow problems with this approach. end TRUNCATE; Fortunately, there is a new secondary standard from NUMWG which will provide a better-defined alternative; the proposed standard package GENERIC_PRIMITIVE_FUNCTIONS will provide a TRUNCATE function: function TRUNCATE (X : FLOAT_TYPE) return FLOAT_TYPE; -- may raise PRIMITIVE_FUNCTIONS_EXCEPTIONS.REPRESENTATION_ERROR I'm told that there will be an article posted in the near future which gives a comprehensive description of ths proposed standard, as well as another similar proposed standard package, GENERIC_ELEMENTARY_FUNCTIONS, so stay tuned. Bill Wolfe, wtwolfe@hubcap.clemson.edu