Mailing List Archive: 49091 messages

## [REBOL] Re: Limiting Precision of Decimals,

### From: greggirwin:mindspring at: 24-May-2002 16:58

```
Hi Louis,

<< Is there any way to avoid scientific notation on decimals?  For example,
I
don't want the E-2 at the end of the following number my program has
calculated: >>

Here's a rounding function that might do what you want.

mod: func [
{Compute a remainder.}
value1 [number! money! time!] {The dividend}
value2 [number! money! time!] {The divisor}
/euclid {Compute a non-negative remainder such that: a = qb + r and
r < b}
/local r
] [
either euclid [
either negative? r: value1 // value2 [r + abs value2] [r]
;-- Alternate implementation
;value1 // value2 + (value2: abs value2) // value2
][
value1 // value2
]
]

;-- Note: to-interval does mod-like rounding. If the interval you
;         specify is not evenly divisble into your base, the result
;         may not be what you expect. E.g. round/to-interval 133 30
;         will round to 120, not 130, because 120 is an even multiple
round: func [
{Rounds numeric value with refinements for what kind of rounding
you want performed, how many decimal places to round to, etc.}
value [number! money! time!] {The value to round}
/up         {Round away from 0}
/floor      {Round towards the next more negative digit}
/ceiling    {Round towards the next more positive digit}
/truncate   {Remaining digits are unchanged. (a.k.a. down)}
/places     {The number of decimal places to keep}
pl [integer!]
/to-interval {Round to the nearest multiple of interval}
interval [number! money! time!]
/local
factor
][
;-- places and to-interval are redundant. E.g.:
;       places 2 = to-interval .01
;   to-interval is more flexible so I may dump places.
;-- This sets factor in one line, under 80 chars, but is it clearer?
;factor: either places [10 ** (- pl)][either to-interval
[interval]]
factor: either places [
10 ** (negate pl)
] [
either to-interval [interval] 
]
;-- We may set truncate, floor, or ceiling in this 'if block.
if not any [up floor ceiling truncate] [
;-- Default rounding is even. Should we take the specified
;   decimal places into account when rounding? We do at the
;   moment.
either (abs value // factor) <> (.5 * factor) [
value: (.5 * factor) + value
return value - mod/euclid value factor
] [
;-- If we get here, it means we're rounding off exactly
;   .5 (at the final decimal position that is).
either even? value [
truncate: true
] [
either negative? value [floor: true][ceiling: true]
]
]
]
if up       [either negative? value [floor: true][ceiling: true]]
if truncate [return value - (value // factor)]
if floor    [return value - mod/euclid value factor]
if ceiling  [return value + mod/euclid (negate value) factor]
]

--Gregg
```