Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
float to int conversion
#1
i have a floating point number that is a power (whole, perhaps negative, but not too extreme) of 2 and therefore can be represented in floating point exactly. an example of such a number is 2 to the -2 power which is 0.25. i might have other numbers, but the issue i am seeing is with those that are powers of 2. i also have a very large power of 10 such 10**32. typically i will have much larger but i picked 10**32 so the numbers i will show are not too long. if i have 0.125 and 10**32 and multiply them and convert back to int i am wanting to get 12500000000000000000000000000000 but the value i actually get is 12500000000000000670770275549184. the issue appears to be the int() conversion is working with a reduced number resolution that is unable to represent 1.25e-31 exactly (double in C on x86 can, even on 32 bit platforms), or is unable to represent a conversion temporary value exactly.

what i am looking for is a way to carry out the multiplication of a very large int to get a very large int by a float value that has an exact representation and get a "clean" result. one complication is that the original int number and expected result int number do not have exact representations in float (so doing it all in float isn't usable).
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
Fraction might solve your problem.
from fractions import Fraction
a = Fraction.from_float(0.125)
n = a * 10 ** 32
print(n)

It seem to work better as strings.
from fractions import Fraction
print(Fraction(0.1), Fraction(str(0.1)))
99 percent of computer problems exists between chair and keyboard.
Reply
#3
In addition to using rational arithmetic, the decimal module can also be used.

>>> from decimal import Decimal
>>> Decimal(0.125) * 10**32
Decimal('1.250000000000000000000000000E+31')
>>> int(_)
12500000000000000000000000000000
In recent versions of Python, binary floats are converted exactly to Decimal by allowing the precision of the result to be increased. 53 decimal digits is sufficient to represent a 53-bit binary value. Since your float value is an exact power of 2, this doesn't really matter but it can be useful.

The default precision of a result is 28 decimal digits. You can increase that if your expected result is larger.
Reply
#4
i solved this by scaling the number, whatever it is, by a sufficient power of 2 to eliminate any fractional part and converted that to int. now this number is scaled by that power of 2. next, i do the multiply. eventually it will be unscaled. actually the 10**32 iyself is a scaling factor. so i am just doing one scaling (by a power of 2) then changing the scaling (to a power of 10) by multiplying the new scaling amount (10**32) and then dividing (int division ... // in Python3) by the old scaling amount (2**?).
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#5
You can use the expression
x & (1 + ~x)
to get the largest power of two that divides x, where x is a nonzero integer. For example
>>> x = 10 ** 32
>>> x
100000000000000000000000000000000
>>> x & (1 + ~x)
4294967296
>>> (x & (1 + ~x)).bit_length() - 1
32
Reply
#6
I always found that string Fractions are more accurate the Decimals.
from decimal import Decimal
from fractions import Fraction

scale = 10 ** 32
value = 0.1
print(int(Decimal(value) * scale))
print(int(Fraction(value) * scale))
print(int(Fraction(str(value)) * scale))
Output:
10000000000000000555111512310000 10000000000000000555111512312578 10000000000000000000000000000000
99 percent of computer problems exists between chair and keyboard.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  python calculate float plus float is incorrect? sirocawa 6 293 Apr-16-2024, 01:45 PM
Last Post: DeaD_EyE
  Comaparing Float Values of Dictionary Against A Float Value & Pick Matching Key firebird 2 3,397 Jul-25-2019, 11:32 PM
Last Post: scidam

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020