Round and Truncate functions

Dave Reyes

New Member
I need help about these two functions.
I can't differentiate them.

And also, I have this task wherein I need to automatically round off to the nearest ones whenever the digit has a decimal value. Is there a built-in function/procedure for that? I don't think Round and Truncate is correct to use for that.
 

TomBascom

Curmudgeon
round( 1. 0, 0 ) = 1
round( 1.1, 0 ) = 1
...
round( 1.5, 0 ) = 2
round( 1.6, 0 ) = 2
...
round( 1.9, 0 ) = 2

truncate( any_of_the_above, 0 ) = 1
 

Dave Reyes

New Member
So TRUNCATE just removes the decimal places and retains integer?
Hmm. So can I use TRUNCATE to my expressions and then add 1 for the automatic round off?
 

TomBascom

Curmudgeon
This really isn't that hard. The documentation is quite clear.

Truncate simply removes the decimal portion at the indicated precision.

Round, rounds. Rounding means to return the closest value to the given precision -- the simple case that you may recall from school is precision 0 or rounding to the nearest integer. That's what I showed above. And that is what you are being asked to do: "I need to automatically round off to the nearest ones". That is exactly what round( x, 0 ) does.

You might try reading this: http://en.wikipedia.org/wiki/Nearest_integer_function

If, in spite of what you say above, you are actually trying to "round up" (sometimes referred to as a "ceiling" function) then you need to create a new function as neither the TRUNCATE() nor ROUND() functions will do what you need. For instance:
Code:
function roundUp returns decimal( x as decimal, p as integer ):
  if truncate( x, p ) = x then
    return x.
   else
    return truncate( x, p ) + exp( 0.1, p ).
end.

Simply adding 0.9 (or any other value) and then truncating WILL NOT WORK. You have to test for the case where the value needs no adjustment -- i.e. x = truncate( x ).
 

Marian EDU

Member
Simply adding 0.9 (or any other value) and then truncating WILL NOT WORK. You have to test for the case where the value needs no adjustment -- i.e. x = truncate( x ).

not sure if the OP needs ceiling or truncate (floor) but I think he was looking for an integer not another decimal... anyway, one do have to test a case here but that will be if the number is negative in which case nothing need to get added just truncate to zero decimals the input value.

Code:
function ceiling returns integer (n as decimal):
  if n > 0 then
  return integer( truncate(n + 0.9, 0)).
  else
  return integer(truncate (n, 0)).
end.
 

TomBascom

Curmudgeon
Our original poster did not specify that he needs an integer result -- however, if that is true then his answer is even simpler. Just use the INTEGER() function. It rounds decimals to the nearest 1. "I need to automatically round off to the nearest ones". He didn't explicitly ask for an integer result but if that was just an oversight then INTEGER() is perfect.

"Rounding" functions that use any technique similar to "add .9" or "add 0.5" in an attempt to avoid testing for input that is already rounded are always flawed. Yours fails if the input is 1.01.
 

Marian EDU

Member
"Rounding" functions that use any technique similar to "add .9" or "add 0.5" in an attempt to avoid testing for input that is already rounded are always flawed. Yours fails if the input is 1.01.

I stand correctly, looks like at least one of us does occasionally know something about 4gl and not only pretending :)
 

LarryD

Active Member
Just to be contrary and throw another wrench or 2 into this interesting discussion, there is also the issue of negative numbers.

e.g. -1.6

Tom's function returns zero
Marian's function returns -1
round(-1.6,0) returns -2
truncate(-1.6,0) returns -1
integer(-1.6) returns -2
e.g. -1.1

Tom's function returns zero
Marian's function returns -1
round(-1.1,0) returns -1
truncate(-1.1,0) returns -1
integer(-1.1) returns -1
 

TomBascom

Curmudgeon
True, I made no attempt to deal with negative numbers.
Code:
function roundUp returns decimal( x as decimal, p as integer ):
  if truncate( x, p ) = x then
    return x.
   else
    if x > 0 then
      return truncate( x, p ) + exp( 0.1, p ).
     else
      return truncate( x , p ) - exp( 0.1, p ).
end.
 

LarryD

Active Member
Negative numbers beg the question as to what is rounding UP.... should -1.1 round "up" to -2 or should it be -1?

Not that I have an answer, just something I've wondered about how software should actually treat rounding up (or down) of negative numbers.
 

Stefan

Well-Known Member
http://en.wikipedia.org/wiki/Rounding#Rounding_to_integer

Code:
DEF VAR de AS DECIMAL EXTENT 9 INITIAL [ 23.67, 23.50, 23.35, 23.00, 0, -23.00, -23.35, -23.50, -23.67 ].
DEF VAR ii AS INT.
DEF VAR cc AS CHAR.

DO ii = 1 TO EXTENT( de ):

   cc =  SUBSTITUTE( 
            "&1&2~t&3~n":u,
            cc,
            STRING( de[ii], "->9.99" ),
            ROUND( de[ii], 0 )

         ).
END.

MESSAGE cc VIEW-AS

So Progress rounds to nearest (last column in wiki table) - which is imho the 'normal' way of rounding (ignore the sign, round, then restore the sign).
 

TomBascom

Curmudgeon
Negative numbers beg the question as to what is rounding UP.... should -1.1 round "up" to -2 or should it be -1?

Not that I have an answer, just something I've wondered about how software should actually treat rounding up (or down) of negative numbers.

Negative Up = Down ;)

Or you could get all technical like Stefan...
 

LarryD

Active Member
I know how it works for all software... it was more a philosophical question than a practical one.

Thanks for all of this... it's been interesting.
 

Dave Reyes

New Member
Wow. Great codes guys.
But I think what I really needed is what Tom said, the "Ceiling" procedure, which I think Progress doesn't have.

I'll try out all your codes with my procedure to check which fit/compute best.
Thank you all and God Bless. :)
 
Top