8 replies to this topic

#1 IceMetalPunk

IceMetalPunk

InfiniteIMPerfection

• Retired Staff
• 9259 posts
• Version:Unknown

Posted 29 August 2011 - 11:45 PM

I'm trying to remove the radix point (decimal point) from a number without converting it to a string. For example, the number 15.15 should be converted to 1515, again, no strings involved.

Perhaps I'm missing a simpler method, but I've tried using a while() loop like this:

```while (floor(val) != val) {
val *= 10;
}```

But precision errors completely messed that up. My test of 15.15 ended up being changed to 15.14999999999999999999999999999, which caused the loop to crash with an unexpected error after 20 iterations.

Is there another way to do this? Or else a way around the precision issues? And yes, I do have a reason for not wanting to convert to a string, so please don't suggest that.

-IMP
• 0

#2 Data-Fi

Data-Fi

GMC Member

• GMC Member
• 36 posts
• Version:Unknown

Posted 29 August 2011 - 11:56 PM

What about flooring the number and then subtracting that from the number, so it could be 15.15 - 15 = .15
then you could, if that number is greater than 0, multiply both numbers by 10, and repeat until the floored number = then number.
I wouldn't use this code because I suck at 'do' statements but something like
do
{if floor(x) = x = false
{x = floor(x)*10 + (floor(x)-x)*10}}
until floor(x) = x

and again I hardly have success with do statements.
oops sorry if this isn't useful because it seems identical to what you wrote, only its
like 10 times as long. Maybe that precision error will be voided this way or something.

Edited by Mr. Skellington, 30 August 2011 - 12:02 AM.

• 0

#3 IceMetalPunk

IceMetalPunk

InfiniteIMPerfection

• Retired Staff
• 9259 posts
• Version:Unknown

Posted 30 August 2011 - 12:12 AM

That's basically what I'm doing now. But since 0.15 is represented in memory as 0.149999999999999385 something, it doesn't work very well...meaning it doesn't work at all.

-IMP
• 0

#4 Data-Fi

Data-Fi

GMC Member

• GMC Member
• 36 posts
• Version:Unknown

Posted 30 August 2011 - 12:38 AM

That's basically what I'm doing now. But since 0.15 is represented in memory as 0.149999999999999385 something, it doesn't work very well...meaning it doesn't work at all.

-IMP

that's pretty boggling, what about rounding that number, as you multiply by ten?
or just check if the difference between the floored val and the val is less than .00001

Edited by Mr. Skellington, 30 August 2011 - 12:40 AM.

• 0

#5 IceMetalPunk

IceMetalPunk

InfiniteIMPerfection

• Retired Staff
• 9259 posts
• Version:Unknown

Posted 30 August 2011 - 12:40 AM

If I round the number, how will I know if there are any more actual decimal places to process?

And it's not really boggling; it's just the precision of doubles that's messing this all up.

-IMP
• 0

#6 Data-Fi

Data-Fi

GMC Member

• GMC Member
• 36 posts
• Version:Unknown

Posted 30 August 2011 - 01:09 AM

If I round the number, how will I know if there are any more actual decimal places to process?

And it's not really boggling; it's just the precision of doubles that's messing this all up.

-IMP

I was suggesting that you could say something like
if abs(round(val) - val) < .00000001
you can end your while statement.
• 0

#7 torigara

torigara

GMC Member

• GMC Member
• 6483 posts

Posted 30 August 2011 - 01:51 AM

Since computers store real numbers in a binary representation, it can't represent an exact decimal number. For instance, when you write 15.15, it is translated into the following value:
(1 + 1/2 + 1/4 + 1/8 + 1/64 + 1/512 + ... + 1/4503599627370496) << 3 = 1.89375(approx) * 8
That isn't equal to the decimal number 15.15000... at the first place. It essentially has an infinite number of decimal places (the more precision you request, the more decimal places it would reveal.) So, it is impossible to "remove" the decimal point unless the fractional part is some nice number like 0.5, 0.75 etc.

In general, when you use a real number you always have to take account of precision errors and put the allowable margin of error on comparison.
```if (value1 == value2) ... // Wrong
if (abs(value1 - value2) < tolerance) // Correct```
I'm not sure how to apply a tolerance on your case, though. For what purpose you need it?

Edited by torigara, 30 August 2011 - 02:12 AM.

• 0

#8 IceMetalPunk

IceMetalPunk

InfiniteIMPerfection

• Retired Staff
• 9259 posts
• Version:Unknown

Posted 30 August 2011 - 02:16 AM

Since computers store real numbers in a binary representation, it can't represent an exact decimal number. For instance, when you write 15.15, it is translated into the following value:
(1 + 1/2 + 1/4 + 1/8 + 1/64 + 1/512 + ... + 1/4503599627370500) << 3 = 1.89375(approx) * 8
That isn't the exact decimal number 15.15000... at the first place. It essentially has an infinite number of decimal places (the more precision you request, the more decimal places it would reveal.) So, it is impossible to "remove" the decimal point.

In general, when you use a real number you always have to take account of precision errors and put the allowable margin of error on comparison.

```if (value1 == value2) ... // Wrong
if (abs(value1 - value2) < tolerance) // Correct```
I'm not sure how to apply a tolerance on your case, though. For what purpose you need it?

Hm. Well, I was trying to write my own string() function, just for educational purposes. I've got it working easily for integers, but I'm having trouble converting the decimals into strings. I thought it would be easier if I could just convert the fractional part of the number to an integer first, then run through the same process I'm currently using for the integers...

I suppose this is why the internal string() function rounds to 2 places?

-IMP

Edited by IceMetalPunk, 30 August 2011 - 02:18 AM.

• 0

#9 torigara

torigara

GMC Member

• GMC Member
• 6483 posts

Posted 30 August 2011 - 08:07 AM

Well, you basically have to specify the number of decimal places you want, then approximate the decimal number up to the indicated precision. (Optionally, you can truncate zeroes at the end after the conversion.)

There found a few algorithms to get an optimal output, but they don't seem to be simple either:
Printing Floating-Point Numbers Quickly and Accurately
Floating point to decimal conversion is not so easy
• 0

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users