mIRC Home    About    Download    Register    News    Help

Print Thread
#196439 16/03/08 04:42 PM
Joined: Mar 2008
Posts: 2
N
Nvv Offline OP
Bowl of petunias
OP Offline
Bowl of petunias
N
Joined: Mar 2008
Posts: 2
Has been verified on multi systems with version untill 6.31

a search on this forum with $round as search criteria didn't displays a topic, apologies is it already mentioned somewhere.

//echo $round(16.15,1)
returns a result of 16.1

from 0.15 - 15.15 $round returns a correct answer.

Nvv #196440 16/03/08 05:31 PM
Joined: Aug 2007
Posts: 334
Pan-dimensional mouse
Offline
Pan-dimensional mouse
Joined: Aug 2007
Posts: 334
this isn't a bug

Quote:
$round(N,D)

Returns the specified floating point number rounded to the Dth decimal digit.



$round(3.14159,2) returns 3.14



The D parameter is optional.


This is not the signature you are looking for
Nvv #196441 16/03/08 05:35 PM
Joined: Jul 2006
Posts: 4,157
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,157
Originally Posted By: Nvv
from 0.15 - 15.15 $round returns a correct answer.
Not only, after some testing i've noticed that after an integer > 262143, the correct value is returned
Code:
$round(262143.15,1) return 262143.1
$round(262144.15,1) return 262144.2


*Why this number* is certainly a story of "bits" but i don't know much about that.


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
foshizzle #196443 16/03/08 06:06 PM
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
I don't think you understand what this report is about. A help file quote is insufficient and largely irrelevant.

$round(16.15,1) should return 16.2, not 16.1; it's how rounding works (which is not simply chopping off extra decimal digits).


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
Nvv #196449 16/03/08 07:38 PM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
This is unfortunately not a bug. This is an issue with floating point arithmetic and floating point roundoff (google it), very well known issues when dealing with floating point numbers on a computer.

Here's why... Using Python, a language that properly represents floating points, you quickly see the following output:

Originally Posted By: Python

>> 16.15
16.149999999999999
>>


This is the same in C:

Quote:

main() {
double f = 16.15;
if (f == 16.15f)
printf("This value is 16.15\n");
else
printf("This value is not 16.15\n");
}

output: This value is not 16.15


Therefore we clearly see that rounding to 2 digits in Python would do the exact same thing it does in mIRC. We also see that C cannot do comparisons on certain floats. Is this a global programming language bug? Should C be changed? Should Python fix this too?

The answer is no, and it can't. The reason you see this is because of floating point roundoff. 16.15 may seem like a perfectly natural number to you as a human who uses base-10 to represent numbers, but in a computer, where the number 16.15 is represented in base-2, this value is a repeating decimal. Short conclusion: there is no way to accurately represent the number 16.15 in a computer.

The only way to work around this would be for K to treat the number as a string and not convert it to a floating point in the computer which would mangle the value..

Here are some extra readings on the issue of comparing floating points, to see that you are not alone and so you can see why you will for the rest of your 32bit life see floating point issues in just about any language you use:

http://docs.python.org/tut/node16.html

http://ajax.suaccess.org/ruby/comparing-floating-point-numbers/

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/280905

http://en.wikipedia.org/wiki/Floating_point

Here's a math heavy one for the real geeks:
http://docs.sun.com/source/806-3568/ncg_goldberg.html


edit:

You can use this mIRC code as a workaround-- $roundp(16.15,1) == 16.2:

Code:
alias roundp {
  var %p = $pos($1,.,1)
  if (!%p) return $1
  var %r, %p = $calc(%p + $2 + 1)
  if ($mid($1, %p, 1) >= 5) {
    %r = $left($calc($left($1, %p) + $&
      $calc(10 ^ $+(-,$2))), $calc(%p - 1))
  }
  else { 
    %r = $left($1, $calc(%p - 1))
  }
  return $iif($right(%r,1) == ., $int(%r), %r)
}

Last edited by argv0; 16/03/08 08:29 PM.

- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #196450 16/03/08 07:54 PM
Joined: Mar 2008
Posts: 2
N
Nvv Offline OP
Bowl of petunias
OP Offline
Bowl of petunias
N
Joined: Mar 2008
Posts: 2
Impressive and interesting.
Thank you very much 4 the references & workaround.


Link Copied to Clipboard