By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,836 Members | 1,983 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,836 IT Pros & Developers. It's quick & easy.

Proposal: Decimal literals in Python.

P: n/a
Python has had the Decimal data type for some time now. The Decimal data
type is ideal for financial calculations. Using this data type would be
more intuitive to computer novices than float as its rounding behaviour
matches more closely what humans expect. More to the point: 0.1 and 0.01
are exact in Decimal and not exact in float.

Unfortunately it is not very easy to access the Decimal data type. To obtain
the decimal number 12.34 one has to do something like this:

import decimal
x=decimal.Decimal("12.34")

Of course we can intruduce a single character function name as an alias for
the Decimal type constructor, but even then we have to use both parentheses
and quotes for each and every decimal constant. We cannot make it shorter
than D("12.34")

With Python 3000 major changes to the language are carried out anyway. My
proposal would require relatively minor changes.

My proposal:
- Any decimal constant suffixed with the letter "D" or "d" will be
interpreted as a literal of the Decimal type. This also goes for
decimal constants with exponential notation.

Examples of decimal literals:
1d
12.34d
1e-3d (equivalent to 0.001d)
1e3d (same value as 1000d, but without trailing zeros).
1.25e5d (same value as 125000d but without trailing zeros).

When we print a decimal number or convert it to a string with str(), a
trailing d should not be added. The repr function does yield strings with a
trailing d.

When decimal numbers are converted from strings, both numbers with and
without a trailing d should be accepted.

If we have decimal literals in the core language, we should probably have a
type constructor in the core namespace, e.g. dec() along with int()
and float(). We then need the decimal module only for the more advanced
stuff like setcontext.

Pros:
- the Decimal data type will be more readily accessible, especially
for novices.
- Traling characters at the end of a literal are already used (the L
for long).
- It does not conflict with the syntax of other numeric constants or
language constructs.
- It does not change the meaning of existing valid literal constants.
Constants that used to be float will continue to do so.

Cons:
- The lexical scanner of the Python interpreter will be slightly more
complex.
- The d suffix for constants with exponential notation is ugly.
- Decimal numbers with exponentail notation like 2e5d could be mistaken
for hex (by humans, not by the parser as hex requires the 0x prefix).
- It requires the decimal module to be part of the core Python
interpreter.

--
Lennart

Oct 26 '07 #1
Share this Question
Share on Google+
25 Replies


P: n/a
Lennart Benschop <le******@xs4all.nlwrites:
Python has had the Decimal data type for some time now.
Since version 2.4 <URL:http://www.python.org/dev/peps/pep-0327>.
Unfortunately it is not very easy to access the Decimal data
type. To obtain the decimal number 12.34 one has to do something
like this:

import decimal
x=decimal.Decimal("12.34")
Slightly nicer, if you need to create a lot of them::
>>from decimal import Decimal
foo = Decimal("12.34")
Of course we can intruduce a single character function name as an
alias for the Decimal type constructor, but even then we have to use
both parentheses and quotes for each and every decimal constant. We
cannot make it shorter than D("12.34")
Nor should we. A function or type name should be short but explicit,
and 'Decimal' is about as short as I'd want.
With Python 3000
"Python 3000" is now in beta development, and is called Python version
3.0.
major changes to the language are carried out anyway.
All of which have been decided for some time now. It's rather too late
to introduce behaviour changes and hope for them to be in Python 3.0.
My proposal:
Feel free to file an actual proposal using the PEP process. You might
want to refer to the PEP that introduced the Decimal type for
inspiration.

--
\ "How many people here have telekenetic powers? Raise my hand." |
`\ -- Emo Philips |
_o__) |
Ben Finney
Oct 26 '07 #2

P: n/a
On Fri, 26 Oct 2007 19:19:46 +1000, Ben Finney wrote:
>Of course we can intruduce a single character function name as an alias
for the Decimal type constructor, but even then we have to use both
parentheses and quotes for each and every decimal constant. We cannot
make it shorter than D("12.34")

Nor should we. A function or type name should be short but explicit, and
'Decimal' is about as short as I'd want.
You don't like str, int, float, list, set, dict, or bool?

Or for that matter, enum
http://www.python.org/dev/peps/pep-0354/

*wink*
--
Steven.
Oct 26 '07 #3

P: n/a
Steven D'Aprano <st***@REMOVE-THIS-cybersource.com.auwrites:
On Fri, 26 Oct 2007 19:19:46 +1000, Ben Finney wrote:
Nor should we. A function or type name should be short but
explicit, and 'Decimal' is about as short as I'd want.

You don't like str, int, float, list, set, dict, or bool?
They'd all make lousy names for a decimal type.

--
\ "Whatever you do will be insignificant, but it is very |
`\ important that you do it." -- Mahatma Gandhi |
_o__) |
Ben Finney
Oct 26 '07 #4

P: n/a

D = lambda x: decimal.Decimal(str(x))
>D(3.2)
Decimal("3.2")

Steven D'Aprano wrote:
On Fri, 26 Oct 2007 19:19:46 +1000, Ben Finney wrote:

>>Of course we can intruduce a single character function name as an alias
for the Decimal type constructor, but even then we have to use both
parentheses and quotes for each and every decimal constant. We cannot
make it shorter than D("12.34")
Nor should we. A function or type name should be short but explicit, and
'Decimal' is about as short as I'd want.

You don't like str, int, float, list, set, dict, or bool?

Or for that matter, enum
http://www.python.org/dev/peps/pep-0354/

*wink*

--
Shane Geiger
IT Director
National Council on Economic Education
sg*****@ncee.net | 402-438-8958 | http://www.ncee.net

Leading the Campaign for Economic and Financial Literacy
Oct 26 '07 #5

P: n/a
- Traling characters at the end of a literal are already used (the L
for long).
The trailing L is going away in Python 3.0. For your consideration may
I suggest a '$' prefix. Though, I'm not sure I even support the idea
of a decimal literal, and I'm not even sure if I support the idea of
using a prefix '$' to identify that literal, it seems somewhat
fitting.

So...
Decimal("12.34") -$12.34

Pros:
- Easier to see than appended character (I think)
- Notation is fitting when dealing with monetary values
- Easy to remember
Cons:
- Maybe too clever for its own good. Some people may be confused to
find out that it isn't actually a monetary type.

I'm sure there are more...

Matt
Oct 26 '07 #6

P: n/a
Matimus <mc******@gmail.comwrites:
The trailing L [for 'long' literals] is going away in Python 3.0.
Yes. On the other hand, we are gaining '0bNNNN' for binary literals,
to go along with '0oNNNN' for octal and '0xNNNN' for hexadecimal.

So, the original poster might get further by proposing an '0dNNN.NNN'
syntax for 'decimal.Decimal' literals. At least the syntax would be
consistent and wouldn't add a new punctuation character to the
language...
For your consideration may I suggest a '$' prefix.
.... unlike this one.

--
\ "The illiterate of the future will not be the person who cannot |
`\ read. It will be the person who does not know how to learn." |
_o__) -- Alvin Toffler |
Ben Finney
Oct 26 '07 #7

P: n/a
Matimus wrote:
>- Traling characters at the end of a literal are already used (the L
for long).

The trailing L is going away in Python 3.0. For your consideration may
I suggest a '$' prefix. Though, I'm not sure I even support the idea
of a decimal literal, and I'm not even sure if I support the idea of
using a prefix '$' to identify that literal, it seems somewhat
fitting.

So...
Decimal("12.34") -$12.34

Pros:
- Easier to see than appended character (I think)
- Notation is fitting when dealing with monetary values
- Easy to remember
Cons:
- Maybe too clever for its own good. Some people may be confused to
find out that it isn't actually a monetary type.
I'm sure there are more...
- Too U.S. centric. Euro would be a slight improvement, as it doesn't
privilege one country, but still too region-centric. Generic currency
marker from ISO 8859-1 would be even less unnecessarily specific, but
also too obscure.
- Looks funny if you use more or fewer than 2 decimal places.
- Sacrifices clarity of meaning for brevity.
>
Matt
My only problem with Decimal("12.34") is the quotation marks. It makes
it look like a string type.

Cheers,
Cliff

Oct 26 '07 #8

P: n/a
Ben Finney wrote:
Matimus <mc******@gmail.comwrites:

>The trailing L [for 'long' literals] is going away in Python 3.0.

Yes. On the other hand, we are gaining '0bNNNN' for binary literals,
to go along with '0oNNNN' for octal and '0xNNNN' for hexadecimal.

So, the original poster might get further by proposing an '0dNNN.NNN'
syntax for 'decimal.Decimal' literals.
It would rather be remarkably inconsistent and confusing.

Python 3.0a1 (py3k:57844, Aug 31 2007, 16:54:27) [MSC v.1310 32 bit
(Intel)] on win32
<snip>
>>type(0b1)
<type 'int'>
>>type(0o1)
<type 'int'>
>>type(0x1)
<type 'int'>
>>assert 0b1 is 0x1
<hypothetical code>
>>type(0d1)
<class 'decimal.Decimal'>
>>assert 0b1 is 0d1
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
assert 0b1 is 0d1
AssertionError

</hypothetical code>

It would also be unkind to people with dyslexia.

Cheers,
Cliff

Oct 26 '07 #9

P: n/a
On Oct 26, 4:54 am, Lennart Benschop <lenna...@xs4all.nlwrote:
Python has had the Decimal data type for some time now. The Decimal data
type is ideal for financial calculations. Using this data type would be
more intuitive to computer novices than float as its rounding behaviour
matches more closely what humans expect. More to the point: 0.1 and 0.01
are exact in Decimal and not exact in float.

Unfortunately it is not very easy to access the Decimal data type. To obtain
the decimal number 12.34 one has to do something like this:

import decimal
x=decimal.Decimal("12.34")

Of course we can intruduce a single character function name as an alias for
the Decimal type constructor, but even then we have to use both parentheses
and quotes for each and every decimal constant. We cannot make it shorter
than D("12.34")

With Python 3000 major changes to the language are carried out anyway. My
proposal would require relatively minor changes.

My proposal:
- Any decimal constant suffixed with the letter "D" or "d" will be
interpreted as a literal of the Decimal type. This also goes for
decimal constants with exponential notation.
This brings something to mind.

One thing I've always thought would be cool would be to have
programmable literals. (Note: Python 3 has a ban on programmable
syntax, and this is clearly falls under that umbrella, although in a
limited form. So this is not a proposal of any sort, just idle
chatter. :)

The idea is: the compiler would see the literal, evaluate it at
compile time, and marshal the evaluated value into the *.pyc file.
More easily said than done, yes, and I'm aware of the issues in doing
that. But it'd be pretty useful, I'd think.

Decimal literals has been mentioned.

In fact it could benefit a lot of numeric objects, such as those in
gmpy.

Regular expressions. A significant speed deficiency of regexps in
Python relative to Perl is that Python has to compile regular
expressions every time the program is invoked. What if you could
compile the regexp at, you know, compile time, and marshall the
compiled state? It could speed things up a bit, especially for small,
regexp heavy scripts.

Oh, well, you get the idea. It's not going to happen, but it'd be
cool while not anything crucial.
Carl Banks

Oct 27 '07 #10

P: n/a
On Oct 26, 7:17 pm, "J. Cliff Dyer" <j...@sdf.lonestar.orgwrote:
Matimus wrote:
- Traling characters at the end of a literal are already used (the L
for long).
The trailing L is going away in Python 3.0. For your consideration may
I suggest a '$' prefix. Though, I'm not sure I even support the idea
of a decimal literal, and I'm not even sure if I support the idea of
using a prefix '$' to identify that literal, it seems somewhat
fitting.
So...
Decimal("12.34") -$12.34
Pros:
- Easier to see than appended character (I think)
- Notation is fitting when dealing with monetary values
- Easy to remember
Cons:
- Maybe too clever for its own good. Some people may be confused to
find out that it isn't actually a monetary type.
I'm sure there are more...

- Too U.S. centric. Euro would be a slight improvement, as it doesn't
privilege one country, but still too region-centric. Generic currency
marker from ISO 8859-1 would be even less unnecessarily specific, but
also too obscure.
FYI: The $ sign is used to denote currency in many countries; as a
rule of thumb countties that call their currency "dollars" or "pesos"
use the $. So Mexico, Canada, Australia, much of Latin America, much
of the Pacific, not to mention countries in Africa (Zimbabwe) and Asia
(Singapore).

It's certainly less region-specific than the Euro is.
Carl Banks

Oct 27 '07 #11

P: n/a

"Shane Geiger" <sg*****@ncee.netwrote in message
news:47**************@ncee.net...
a buggy hack (copying your top post style)
>>D(123456789.123456789)
Decimal("123456789.123")

Or what there an unwritten :-)?

| D = lambda x: decimal.Decimal(str(x))
|
| >D(3.2)
| Decimal("3.2")

Oct 27 '07 #12

P: n/a
On Fri, 26 Oct 2007 19:29:47 -0400, J. Cliff Dyer wrote:
Ben Finney wrote:
>So, the original poster might get further by proposing an '0dNNN.NNN'
syntax for 'decimal.Decimal' literals.
It would rather be remarkably inconsistent and confusing.

Python 3.0a1 (py3k:57844, Aug 31 2007, 16:54:27) [MSC v.1310 32 bit
(Intel)] on win32
<snip>
>>>type(0b1)
<type 'int'>
>>>type(0o1)
<type 'int'>
>>>type(0x1)
<type 'int'>
>>>assert 0b1 is 0x1
That this doesn't raise `AssertionError` is an implementation detail.
It's not guaranteed the two objects are really the same.

Ciao,
Marc 'BlackJack' Rintsch
Oct 27 '07 #13

P: n/a
Marc 'BlackJack' Rintsch <bj****@gmx.netwrites:
>>assert 0b1 is 0x1
That this doesn't raise `AssertionError` is an implementation detail.
It's not guaranteed the two objects are really the same.
I think Ben is getting at 0b1 and 0x1 being the same type, while the
proposed 0d1 is a different type. I don't see anything wrong with 1d.
We already have 1j and I don't think that's going away in 3.0.
Oct 27 '07 #14

P: n/a
On Oct 26, 1:54 am, Lennart Benschop <lenna...@xs4all.nlwrote:
My proposal:
- Any decimal constant suffixed with the letter "D" or "d" will be
interpreted as a literal of the Decimal type. This also goes for
decimal constants with exponential notation.
There's nothing new here that hasn't already been proposed and
discussed on python-dev. There were no major objections to the idea;
however, it will need to wait until there is a good C implementation
of the decimal module (which is in the works but coming along very,
very slowly). Also, once we have a C coded decimal object, further
work would be needed to make it integrate well with the rest of the
language (i.e. making sure that everything allows numeric inputs can
handle a decimal object as a possible input).

FWIW, using the decimal module is not at all as onerous as the OP
makes it sound. I write:

from decimal import Decimal as D
print D(1) / D(7) + D('0.123456')

That isn't much of a burden compared with:

print 1d / 7d + 0.123456d

You would still need to import decimal so you can set the context
parameters (like precision and rounding).

Also, most non-toy scripts have *very* few literals in them; instead,
the decimal values arise from calculations, user inputs, and file of
data. Casting those to the correct type is really no more difficult
that it is with other types:

s = raw_input('Input temperature')
print int(s), Decimal(s), float(s)

Raymond
Oct 27 '07 #15

P: n/a
On Oct 27, 12:12 am, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:
Matimus <mccre...@gmail.comwrites:
The trailing L [for 'long' literals] is going away in Python 3.0.

Yes. On the other hand, we are gaining '0bNNNN' for binary literals,
to go along with '0oNNNN' for octal and '0xNNNN' for hexadecimal.

So, the original poster might get further by proposing an '0dNNN.NNN'
syntax for 'decimal.Decimal' literals. At least the syntax would be
consistent and wouldn't add a new punctuation character to the
language...
[snip]
Some languages have or permit 0qNNNN or 0QNNNN for octal to reduce the
chance of confusion of 'O' (oh) with '0' (zero) in uppercase, eg.
0Q123 is clearer than 0O123 (0 oh 123), although lowercase is better,
eg. 0q123 or 0o123.

Oct 27 '07 #16

P: n/a
On Oct 27, 3:09 pm, MRAB <goo...@mrabarnett.plus.comwrote:
On Oct 27, 12:12 am, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:Matimus <mccre...@gmail.comwrites:
The trailing L [for 'long' literals] is going away in Python 3.0.
Yes. On the other hand, we are gaining '0bNNNN' for binary literals,
to go along with '0oNNNN' for octal and '0xNNNN' for hexadecimal.
So, the original poster might get further by proposing an '0dNNN.NNN'
syntax for 'decimal.Decimal' literals. At least the syntax would be
consistent and wouldn't add a new punctuation character to the
language...

[snip]
Some languages have or permit 0qNNNN or 0QNNNN for octal to reduce the
chance of confusion of 'O' (oh) with '0' (zero) in uppercase, eg.
0Q123 is clearer than 0O123 (0 oh 123), although lowercase is better,
eg. 0q123 or 0o123.
Even clearer is not to allow octal literals :) Is there *any* use for
them?

--
Paul Hankin

Oct 27 '07 #17

P: n/a
Even clearer is not to allow octal literals :) Is there *any* use for
them?
+1

I find that anything I have even the remotest inkling of using
octal for can be done just as easily with hex.

-tkc
Oct 27 '07 #18

P: n/a
On Oct 27, 10:27 am, Paul Hankin <paul.han...@gmail.comwrote:
On Oct 27, 3:09 pm, MRAB <goo...@mrabarnett.plus.comwrote:
On Oct 27, 12:12 am, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:Matimus <mccre...@gmail.comwrites:
The trailing L [for 'long' literals] is going away in Python 3.0.
Yes. On the other hand, we are gaining '0bNNNN' for binary literals,
to go along with '0oNNNN' for octal and '0xNNNN' for hexadecimal.
So, the original poster might get further by proposing an '0dNNN.NNN'
syntax for 'decimal.Decimal' literals. At least the syntax would be
consistent and wouldn't add a new punctuation character to the
language...
[snip]
Some languages have or permit 0qNNNN or 0QNNNN for octal to reduce the
chance of confusion of 'O' (oh) with '0' (zero) in uppercase, eg.
0Q123 is clearer than 0O123 (0 oh 123), although lowercase is better,
eg. 0q123 or 0o123.

Even clearer is not to allow octal literals :) Is there *any* use for
them?
The mode argument to os.chmod.

Oct 27 '07 #19

P: n/a
>Even clearer is not to allow octal literals :) Is there *any* use for
>them?

The mode argument to os.chmod.
You mean instead of

import this
os.chmod(filename, os.R_OK | os.W_OK | os.X_OK)

which explicitly (rather than implicitly) spells it out?

-tkc

Oct 27 '07 #20

P: n/a
On Sat, 27 Oct 2007 13:28:02 -0500, Tim Chase wrote:
>>Even clearer is not to allow octal literals :) Is there *any* use for
them?

The mode argument to os.chmod.

You mean instead of

import this
os.chmod(filename, os.R_OK | os.W_OK | os.X_OK)

which explicitly (rather than implicitly) spells it out?
And the equivalent of ``os.chmod(filename, 0777)`` looks like what!?

Ciao,
Marc 'BlackJack' Rintsch
Oct 27 '07 #21

P: n/a
On 2007-10-27, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
On Sat, 27 Oct 2007 13:28:02 -0500, Tim Chase wrote:
>>>Even clearer is not to allow octal literals :) Is there *any* use for
them?

The mode argument to os.chmod.

You mean instead of

import this
os.chmod(filename, os.R_OK | os.W_OK | os.X_OK)

which explicitly (rather than implicitly) spells it out?

And the equivalent of ``os.chmod(filename, 0777)`` looks like what!?
os.chmod(filename, int('777', 8))

It's good enough for most other bases. ;)

--
Neil Cerutti
Oct 27 '07 #22

P: n/a
"Paul Hankin" <p...l.com>wrote:

Even clearer is not to allow octal literals :) Is there *any* use for
them?
I tend to agree with this point of view - but I fear it will set up a howl
of protest amongst the Brits who cut their teeth on 24 bit ICT/ICL
equipment...

- Hendrik
Oct 28 '07 #23

P: n/a
MRAB <go****@mrabarnett.plus.comwrote:
>On Oct 27, 12:12 am, Ben Finney <bignose+hates-s...@benfinney.id.au>
wrote:
>Matimus <mccre...@gmail.comwrites:
The trailing L [for 'long' literals] is going away in Python 3.0.

Yes. On the other hand, we are gaining '0bNNNN' for binary literals,
to go along with '0oNNNN' for octal and '0xNNNN' for hexadecimal.

So, the original poster might get further by proposing an '0dNNN.NNN'
syntax for 'decimal.Decimal' literals. At least the syntax would be
consistent and wouldn't add a new punctuation character to the
language...
[snip]
Some languages have or permit 0qNNNN or 0QNNNN for octal to reduce the
chance of confusion of 'O' (oh) with '0' (zero) in uppercase, eg.
0Q123 is clearer than 0O123 (0 oh 123), although lowercase is better,
eg. 0q123 or 0o123.
My favorite notation for this comes from Ada, which allows arbitrary bases
from 2 to 16, and allows for underscores within numeric literals:

x23_bin : constant := 2#0001_0111#;
x23_oct : constant := 8#27#;
x23_dec : constant := 10#23#;
x23_hex : constant := 16#17#;

The opportunities for obfuscated coding by writing all constants in base 7
boggle the mind.

I'm not convinced you need delimiters on both ends; I think 16'fffe_3777
would be just as good.

Although, now that I think about the original thread, this doesn't have a
neat solution for the decimal problem...
--
Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Oct 28 '07 #24

P: n/a
"Hendrik van Rooyen" <ma**@microcorp.co.zawrote:
>"Paul Hankin" <p...l.com>wrote:
>Even clearer is not to allow octal literals :) Is there *any* use for
them?

I tend to agree with this point of view - but I fear it will set up a howl
of protest amongst the Brits who cut their teeth on 24 bit ICT/ICL
equipment...
As a long-time Control Data employee, I know that 60-bit words and 18-bit
addresses meant that I could do octal arithmetic nearly as fast as decimal.
On the other hand, Python doesn't run on the 6000s...
--
Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Oct 28 '07 #25

P: n/a
En Fri, 26 Oct 2007 23:28:31 -0300, Carl Banks <pa************@gmail.com>
escribi�:
FYI: The $ sign is used to denote currency in many countries; as a
rule of thumb countties that call their currency "dollars" or "pesos"
use the $. So Mexico, Canada, Australia, much of Latin America, much
of the Pacific, not to mention countries in Africa (Zimbabwe) and Asia
(Singapore).
[OT] Furthermore, the $ sign was used originally to denote "pesos", or
Spanish reals (pieces of eight each). It was later that the US adopted the
sign to denote "dollars" too.

--
Gabriel Genellina

Oct 29 '07 #26

This discussion thread is closed

Replies have been disabled for this discussion.