Float bug, how can I quickly fix it please ? :(

Just starting out? Need help? Post your questions and find answers here.
Phlos
User
User
Posts: 85
Joined: Fri May 16, 2003 7:17 pm

Float bug, how can I quickly fix it please ? :(

Post by Phlos »

Code: Select all

Test.f = 1.50
For i = 1 To 5
  Test + 0.30
Next i

Div.f = Round(Test / 1.00, 0) * 0.05

Debug Div ; Should be 0.15 instead of 0.10 ((3.0 / 1.0) * 0.05 = 0.15) ...)
How can I get accurate value in div please ? :?

Running PB 4.10 b4 :wink:
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Change to doubles instead of floats.

Code: Select all

Test.d = 1.50 
For i = 1 To 5 
  Test + 0.30 
Next i 

Div.d = Round(Test / 1.00, 0) *0.05

Debug Div
You will still get some small errors in accuracy but it will be a lot closer to what you are expecting.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

See comments here in the snipet:

Code: Select all

Test.f = 1.50
For i = 1 To 5
  Test + 0.30
Next i
;test.f is now 2.99999....
Div.f = Round(Test, 0) * 0.05 ; Round(2.999999999999999999999999999999,0) is 2.0 , And then 2.0 * 0.05 is 0.1
Debug Div; Correct result is 0.1
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

But, of course, the 2.999999999 part is wrong as it should total 3.0 which it will if you use doubles.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Derek wrote:But, of course, the 2.999999999 part is wrong as it should total 3.0 which it will if you use doubles.
Agree, agree :)
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Phlos
User
User
Posts: 85
Joined: Fri May 16, 2003 7:17 pm

Post by Phlos »

I am not a newbie, I knew why it was bugged Psychophanta :wink:

Derek, I cannot use double for 2 reasons :
- my project is big (5000+ lines) and I use float since the beginning (so many many stuffs to change, and maybe new bug :shock: )
- double doesn't really fix the issue, it hides it better :D

So here is my tricky solution :

Code: Select all

Test.f = 1.50
For i = 1 To 5
  Test + 0.30
Next i

Div.f = Round(ValF(StrF(Test / 1.00)), 0) * 0.05

Debug Div ; Should be 0.15 and it is 0.15 now :D
:lol:
Last edited by Phlos on Sat Oct 27, 2007 2:07 am, edited 1 time in total.
Thade
Enthusiast
Enthusiast
Posts: 266
Joined: Sun Aug 03, 2003 12:06 am
Location: Austria

Post by Thade »

Round is wrong named ... it replaces Floor and Ceil of other languages but does not round in the actual sense.

To get a rounded result always use + 0.5

Code: Select all

Result.f = Round(Test.f+0.5,0)
--------------
Yes, its an Irish Wolfhound.
Height: 107 cm; Weight: 88 kg
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Thade wrote:Round is wrong named ... it replaces Floor and Ceil of other languages but does not round in the actual sense.

To get a rounded result always use + 0.5

Code: Select all

Result.f = Round(Test.f+0.5,0)
Exactly! :!:
So this is perhaps the more elegant solution to take:

Code: Select all

Test.f = 1.50
For i = 1 To 5
  Test + 0.30
Next i
Div.f = Round(Test.f+0.5,0) * 0.05
Debug Div ; Should be 0.15 and it is 0.15 now :D
:wink:
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Yep, Thade is right, the round function doesn't work like you might of learned about rounding but instead rounds up or down depending on your choice so added 0.5 and rounding down works.
User avatar
Demivec
Addict
Addict
Posts: 4270
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Post by Demivec »

Wouldn't it be simpler to use Int() instead of Round()?

Code: Select all

Result.f = Int(Test.f+0.5)
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Yes, but it depends on what Phlos want to do for his program. Round() returns a float while Int() returns a long.
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Phlos
User
User
Posts: 85
Joined: Fri May 16, 2003 7:17 pm

Post by Phlos »

I am sorry guys, but your fix seems to be wrong :shock:
If I have the float value 2.7 and I want the integer part "2", doing Round(2.7 + 0.5, 0) will return me "3" instead of "2" :shock:

You can't fix the float bad accuracy by adding a constant value :)
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

Phlos wrote:I am sorry guys, but your fix seems to be wrong :shock:
If I have the float value 2.7 and I want the integer part "2", doing Round(2.7 + 0.5, 0) will return me "3" instead of "2" :shock:

You can't fix the float bad accuracy by adding a constant value :)
Hi Phlos.

As 2.7 plus 0.5 is 3.2, Round(2.7 + 0.5,0) = Round(3.2,0) = 3 and so is giving you an accurate result, no?

Edit:

By adding 0.5 and rounding down (flooring) you ensure you get anything with a fractional part of .5 or higher to the next whole number and then truncate the digits. Whereas anything with a decimal fraction part under 0.5 the next whole number is not reached and thus is truncated down to the current whole number. This, of course, within the vague-eries of how floating point numbers are stored (an industry standard).
Dare2 cut down to size
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Phlos wrote:If I have the float value 2.7 and I want the integer part "2", doing Round(2.7 + 0.5, 0) will return me "3" instead of "2"
If you just want the integer part then you should use int() not round() as round() implied that you wanted the nearest whole number which is what the +0.5 was obtaining.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Phlos wrote:I am sorry guys, but your fix seems to be wrong :shock:
If I have the float value 2.7 and I want the integer part "2", doing Round(2.7 + 0.5, 0) will return me "3" instead of "2" :shock:

You can't fix the float bad accuracy by adding a constant value :)
At the moment may be this workaround can help you, even it is not very elegant, it helps if you need floats and no doubles:

Code: Select all

Test.f = 1.50 
For i = 1 To 5 
  Test + 0.30 
Next i 
Div.f = Round(Test.f+0.01,0) * 0.05 
Debug Div ; Should be 0.15 and it is 0.15 now :D
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Post Reply