473,503 Members | 1,814 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

long(Decimal) performance

Hello c.l.p.ers :)

Running long(Decimal) is pretty slow, and the conversion is based on
strings. I'm trying to figure out whether there is a good reason for
using strings like in decimal.py (that reason would be bound to bite me
down the road).
This converts Decimal to long and is much faster in my test system
(PIII 650MHz, but was written on a P133 a year ago :)).

def dec2long(number):
"""
Convert decimal.Decimal to long.

Hopefully faster than C{int(Decimal())}.
@param number: A C{decimal.Decimal} value
@return: Long from input
"""
if not isinstance(number, Decimal):
raise TypeError, "dec2long requires an instance of Decimal"
elif number._is_special:
if number._isnan():
raise TypeError, "This Decimal is NaN, an ex-Number"
elif number._isinfinity():
raise OverflowError, "Cannot convert infinity to long"

else:
longstring = str(number)
if "e" in longstring:
longsplit = longstring.split("e")
elif "E" in longstring:
longsplit = longstring.split("E")
else:
longsplit = [longstring, "0"]
floatexp = long(len(longsplit[0].split(".")[1]))
ftol = long(Decimal(longsplit[0]) * 10L**floatexp)
longexp = long(int(longsplit[1]) - floatexp)
result = ftol * 10L**longexp
return result

For the sake of camparison, here's decimal.py __int__:

def __int__(self):
"""Converts self to an int, truncating if necessary."""
[snip: error checking]
if self._exp >= 0:
s = ''.join(map(str, self._int)) + '0'*self._exp
else:
s = ''.join(map(str, self._int))[:self._exp]
if s == '':
s = '0'
sign = '-'*self._sign
return int(sign + s)

Then, some timings:
>example
Decimal("7.252714899122810148399426210E+12378")
>%timeit v = dec2long(example)
10 loops, best of 3: 12 ms per loop
>%timeit v = long(example)
10 loops, best of 3: 283 ms per loop
>dec2long(example) == long(example)
True

Some anachronisms (like 10L) and very probably mistakes are present in
that old hack, but it makes decimal somewhat more interesting for me.

The answer to this message might be "decimal will be written in C very
soon, so nevermind", but I'd love to hear that in fact the following
function is wrong and there is a good reason long(Decimal) works based
on strings... or that my function is silly but could be corrected.

Thanks in advance and best regards,
Daniel 'ajaksu' Diniz

PS: my use case is Stirling's approximation of the factorial for large
numbers, feel free to criticize that, too ;)

Aug 12 '06 #1
3 2360
Sorry... I'm ashamed to submit such awful code in my first post. Let me
try again...

from decimal import Decimal
def dec2long(number):
""" Convert decimal.Decimal to long """
longstring = str(number)
if "e" in longstring:
radix, exponent = longstring.split("e")
elif "E" in longstring:
radix, exponent = longstring.split("E")
else:
radix, exponent = [longstring, "0"]
floatexp = long(len(radix.split(".")[1]))
floatish = Decimal(radix) * 10L**floatexp
ftol = long(floatish)
longexp = long(int(exponent) - floatexp)
return ftol * 10L**longexp

This one should run by itself, is more readable and... still smells bad
:(
Sorry again.

Aug 12 '06 #2
In article <11**********************@b28g2000cwb.googlegroups .com>,
ajaksu <aj****@gmail.comwrote:
>
Running long(Decimal) is pretty slow, and the conversion is based on
strings. I'm trying to figure out whether there is a good reason for
using strings like in decimal.py (that reason would be bound to bite me
down the road).
I'm not sure why it's coded that, but it's somewhat irrelevant: right
now, work is being done to convert decimal.py to C code, which will
almost certainly be much faster than your code. Generally speaking, you
should not be using Decimal now with any expectation of speed.
--
Aahz (aa**@pythoncraft.com) <* http://www.pythoncraft.com/

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by
definition, not smart enough to debug it." --Brian W. Kernighan
Aug 12 '06 #3
Hi Aahz, thanks for the feedback!

Aahz wrote:
I'm not sure why it's coded that, but it's somewhat irrelevant: right
now, work is being done to convert decimal.py to C code, which will
almost certainly be much faster than your code. Generally speaking, you
should not be using Decimal now with any expectation of speed.
Agreed and agreed.

Just to avoid that the buggy (and unreadable) versions above harm
anyone, here's a better attempt:

def dec2long(number):
""" Convert C{decimal.Decimal} to long """
decimal_string = str(number)
## Split 123.45E10 -radix = 123.45, exponent = 10
if "e" in decimal_string:
radix, exponent = decimal_string.split("e")
elif "E" in decimal_string:
radix, exponent = decimal_string.split("E")
else:
radix, exponent = (decimal_string, 0)
if exponent:
exponent = int(exponent)
if "." in radix:
## radix = 123.45, radix_decimal_part_len = 2
radix_decimal_part_len = long(len(radix.split(".")[1]))
## radix = 123.45, radix_as_long = 123.45 * 10**2 = 12345
radix_as_long = long(Decimal(radix) *
(10L**radix_decimal_part_len))
##corrected_exponent = 10 - 2 = 8
corrected_exponent = exponent - radix_decimal_part_len
## return 12345 * 10**8
result = radix_as_long * 10L** corrected_exponent
else:
radix_as_long = long(radix)
result = radix_as_long * 10L**exponent
else:
if "." in radix:
radix_integer_part = long(radix.split(".")[0])
else:
radix_integer_part = long(radix)
result = radix_integer_part
return result
Working from inside decimal.py allows things to work faster, but anyone
wanting speed REALLY shouldn't use Decimal :). Now I'm trying clnum
("Rational and arbitrary precision floating point numbers"):
http://cheeseshop.python.org/pypi/clnum/1.2

Cheers,
Daniel

Aug 12 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
4492
by: Batista, Facundo | last post by:
Here I send it. Suggestions and all kinds of recomendations are more than welcomed. If it all goes ok, it'll be a PEP when I finish writing/modifying the code. Thank you. .. Facundo
7
3581
by: William Payne | last post by:
Hello, I have a variable of type unsigned long. It has a number of bits set (with set I mean they equal one). I need to determine those bits and their position and create new numbers from them. For...
4
9709
by: italia | last post by:
I changed the Fieldsize Property from text to Long Integer and Decimal Places = 6. I had decimals in the original field. But after the transfer, the digits after the decimals are gone. Now...
687
22804
by: cody | last post by:
no this is no trollposting and please don't get it wrong but iam very curious why people still use C instead of other languages especially C++. i heard people say C++ is slower than C but i can't...
3
6120
by: Andres A. | last post by:
I have bunch of unicode characters stored as Decimal is there a easy way of displaying unicode from Decimal numbers or do i have to convert the decimal to hex then display the hex? i ran into a...
3
24703
by: Matt | last post by:
Anybody noticed that SQL Server rounds up if the value is half way between two rounded values, but C#'s Decimal.Round(Decimal,Int32) rounds to nearest even number? >From MSDN: "When d is exactly...
6
35650
by: fctk | last post by:
hello, i'm trying to compile this small program: int main(void) { unsigned long int max; max = 4000000000;
3
2163
by: Daniel | last post by:
I'm writing an application that (among other things) evaluates mathematical expressions. The user enters strings containing literals and names that later get evaluated using the Python interpreter....
2
1542
by: KioKrofov | last post by:
I am writing code in C to print out various data values from some test I am running. The data results come in ints, long ints, floats and doubles. Most data values are required to be in decimal,...
0
7280
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6991
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7460
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5578
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4672
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3154
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1512
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
736
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
380
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.