Recent

Author Topic: Round to nearest integer or round up if exactly in middle?  (Read 19627 times)

Kallaste

  • Newbie
  • Posts: 6
Round to nearest integer or round up if exactly in middle?
« on: April 04, 2017, 01:58:21 am »
Hello,

I know of the function
Code: [Select]
Round(X: Real): Longint which rounds to the nearest whole number unless the input is exactly in the middle of two integers, in which case it will use "banker's rounding" and round to the nearest even integer. Is there a way to tell it not to use banker's rounding, but to simply round up in this case?

If not, I need to figure out the simplest way to get the digits to the right of the decimal place of the input value (i.e., is modulus the simplest way or is there a built in function?) so that I can round it up myself if they are equal to .5. Does anyone have any advice?

Thanks.

Phil

  • Hero Member
  • *****
  • Posts: 2737
Re: Round to nearest integer or round up if exactly in middle?
« Reply #1 on: April 04, 2017, 02:18:26 am »
know of the function
Code: [Select]
Round(X: Real): Longint which rounds to the nearest whole number unless the input is exactly in the middle of two integers, in which case it will use "banker's rounding" and round to the nearest even integer. Is there a way to tell it not to use banker's rounding, but to simply round up in this case?

I think the ancient Str procedure can be used. If I recall correctly, I don't think it uses banker's rounding. Test to be sure.

http://www.freepascal.org/docs-html/rtl/system/str.html

Kallaste

  • Newbie
  • Posts: 6
Re: Round to nearest integer or round up if exactly in middle?
« Reply #2 on: April 04, 2017, 02:38:05 am »
Ha, it works! See, this is why it is good to ask questions on forums. I never would have known about that function. Thank you!

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 881
Re: Round to nearest integer or round up if exactly in middle?
« Reply #3 on: April 04, 2017, 08:09:07 am »
I don't know. Something like this is usually used:
Code: Pascal  [Select][+][-]
  1. function MyRound(AReal:Real):Integer;
  2. begin
  3.   if AReal > 0 then begin
  4.     Result := Trunc(AReal + 0.5);
  5.   end
  6.   else begin
  7.     Result := Trunc(AReal - 0.5);
  8.   end;
  9. end;
  10.  
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

ASerge

  • Hero Member
  • *****
  • Posts: 2477
Re: Round to nearest integer or round up if exactly in middle?
« Reply #4 on: April 04, 2017, 10:05:29 am »
Is there a way to tell it not to use banker's rounding, but to simply round up in this case?
Math.SetRoundMode(rmUp). Example:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. program Project1;
  3.  
  4. uses Math;
  5.  
  6. var
  7.   L, U: LongInt;
  8.   D: Double;
  9. begin
  10.   D := 6.5;
  11.   L := Round(D);
  12.   Math.SetRoundMode(rmUp);
  13.   U := Round(D);
  14.   Writeln('D=', D:0:2, ' L=', L, ' U=', U);
  15.   Readln;
  16. end.

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 881
Re: Round to nearest integer or round up if exactly in middle?
« Reply #5 on: April 04, 2017, 10:36:00 am »
Is there a way to tell it not to use banker's rounding, but to simply round up in this case?
Math.SetRoundMode(rmUp). Example:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. program Project1;
  3.  
  4. uses Math;
  5.  
  6. var
  7.   L, U: LongInt;
  8.   D: Double;
  9. begin
  10.   D := 6.5;
  11.   L := Round(D);
  12.   Math.SetRoundMode(rmUp);
  13.   U := Round(D);
  14.   Writeln('D=', D:0:2, ' L=', L, ' U=', U);
  15.   Readln;
  16. end.
Yeah, and now try 6.3.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

ASerge

  • Hero Member
  • *****
  • Posts: 2477
Re: Round to nearest integer or round up if exactly in middle?
« Reply #6 on: April 04, 2017, 11:00:22 am »
Yeah, and now try 6.3.
Sorry, missed "if they are equal to .5".

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Round to nearest integer or round up if exactly in middle?
« Reply #7 on: April 04, 2017, 12:58:12 pm »
Odd, is it the roundmode not working or does it mean something else?
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   Math.SetRoundMode(rmUp);
  4.   memo1.Lines.Add('5.5: '+inttostr(round(5.5)));
  5.   memo1.Lines.Add('6.5: '+inttostr(round(6.5)));
  6.   memo1.Lines.Add('7.5: '+inttostr(round(7.5)));
  7.   memo1.Lines.Add('8.5: '+inttostr(round(8.5)));
  8. end;
Code: Pascal  [Select][+][-]
  1. 5.5: 6
  2. 6.5: 6
  3. 7.5: 8
  4. 8.5: 8
With MyRound() by Mr.Madguy i get:
Code: Pascal  [Select][+][-]
  1. 5.5: 6
  2. 6.5: 7
  3. 7.5: 8
  4. 8.5: 9

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Round to nearest integer or round up if exactly in middle?
« Reply #8 on: April 04, 2017, 01:13:11 pm »
That looks like a bug... I tested it with FPC trunk and get the same rather funny results...
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 881
Re: Round to nearest integer or round up if exactly in middle?
« Reply #9 on: April 04, 2017, 01:21:55 pm »
Odd, is it the roundmode not working or does it mean something else?
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   Math.SetRoundMode(rmUp);
  4.   memo1.Lines.Add('5.5: '+inttostr(round(5.5)));
  5.   memo1.Lines.Add('6.5: '+inttostr(round(6.5)));
  6.   memo1.Lines.Add('7.5: '+inttostr(round(7.5)));
  7.   memo1.Lines.Add('8.5: '+inttostr(round(8.5)));
  8. end;
Code: Pascal  [Select][+][-]
  1. 5.5: 6
  2. 6.5: 6
  3. 7.5: 8
  4. 8.5: 8
Strange, but it should work like Ceil.
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

balazsszekely

  • Guest
Re: Round to nearest integer or round up if exactly in middle?
« Reply #10 on: April 04, 2017, 01:34:55 pm »
@Thaddy
It's not a bug: "In the case of .5, the algorithm uses "banker's rounding": .5 values are always rounded towards the even number. "
http://www.freepascal.org/docs-html/rtl/system/round.html

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Round to nearest integer or round up if exactly in middle?
« Reply #11 on: April 04, 2017, 02:40:49 pm »
It's not a bug: "In the case of .5, the algorithm uses "banker's rounding": .5 values are always rounded towards the even number. "
http://www.freepascal.org/docs-html/rtl/system/round.html
And when exactly is the setting of SetRoundMode() used?

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 881
Re: Round to nearest integer or round up if exactly in middle?
« Reply #12 on: April 04, 2017, 03:34:52 pm »
Lol. FPC simply precalculates round(constant) value and therefore doesn't respect SetRoundMode.

This doesn't work:
Code: Pascal  [Select][+][-]
  1.   Math.SetRoundMode(rmUp);
  2.   Memo1.Lines.Add('6.5: '+IntToStr(round(6.5)));
  3.  

Cuz it's being "optimized" into:
Code: Pascal  [Select][+][-]
  1.   Math.SetRoundMode(rmUp);
  2.   Memo1.Lines.Add('6.5: '+IntToStr(6));
  3.  

This works:
Code: Pascal  [Select][+][-]
  1.   Math.SetRoundMode(rmUp);
  2.   X := 6.5;//Double
  3.   Y := Round(X);//Integer
  4.   Memo1.Lines.Add('6.5: '+IntToStr(Y));
  5.  
« Last Edit: April 04, 2017, 03:37:39 pm by Mr.Madguy »
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

rvk

  • Hero Member
  • *****
  • Posts: 6953
Re: Round to nearest integer or round up if exactly in middle?
« Reply #13 on: April 04, 2017, 03:42:06 pm »
Yeah, that's real neat.
With the example:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var
  3.   Y: Double;
  4. begin
  5.   Math.SetRoundMode(rmUp);
  6.   Y := 5.5; memo1.Lines.Add('5.5: '+inttostr(round(Y)) + ' or as constant ' + inttostr(round(5.5)));
  7.   Y := 6.5; memo1.Lines.Add('6.5: '+inttostr(round(Y)) + ' or as constant ' + inttostr(round(6.5)));
  8.   Y := 7.5; memo1.Lines.Add('7.5: '+inttostr(round(Y)) + ' or as constant ' + inttostr(round(7.5)));
  9.   Y := 8.5; memo1.Lines.Add('8.5: '+inttostr(round(Y)) + ' or as constant ' + inttostr(round(8.5)));
  10. end;

Code: [Select]
5.5: 6 or as constant 6
6.5: 7 or as constant 6
7.5: 8 or as constant 8
8.5: 9 or as constant 8

Something to be noted in the documentation.

Handoko

  • Hero Member
  • *****
  • Posts: 5524
  • My goal: build my own game engine using Lazarus
Re: Round to nearest integer or round up if exactly in middle?
« Reply #14 on: April 04, 2017, 03:48:20 pm »
@Thaddy
It's not a bug: "In the case of .5, the algorithm uses "banker's rounding": .5 values are always rounded towards the even number. "
http://www.freepascal.org/docs-html/rtl/system/round.html

Banker's Rounding is also called as Round-Half-Even, it is commonly used for financial calculations. Read more here:
http://www.eetimes.com/document.asp?doc_id=1274485
http://mathematica.stackexchange.com/questions/2116/why-round-to-even-integers

 

TinyPortal © 2005-2018