`1e23 != 10 ** 23` now. Possible solution: PyFloatLongObject

Human beings know that

100000000000000000000000.0
1.0e+23

are integers. They are in the group of real numbers, but they are also in the integer group.

My idea is to represent internally these numbers as a new internal type. Temporary name: PyFloatLongObject.

Integers have “infinite” precision. So, 1e23 == 10 ** 23 is False now.

If 1e23 will be internally a PyFloatLongObject, 1e23 == 10 ** 23 will become True.

This behavior can be restricted to only big integers, to not slow down little floats like 10.0

EDIT: The scope is not having an infinite precision for float operations, but an infinite precision for creation of floats that are integers.

I don’t know that. I know that they are both floating point values. Are you saying I’m not a human being?

But it will slow down small floats too, because every single float operation will have to check whether the result is going to be “big enough”, and if so, swap to integer mode. And then if the result is not exactly a power of ten, it will have to swap back again to float mode.

Why don’t you just use Decimal?

1 Like

post deleted by author

I think python already does this. Python uses IEEE floating point doubles. If you read arolund this you will find that if abs(x) less than 2^53 and is an integer IEEE doubles store the exact representation. As long as the result is less that 2**53, +, - and * preserve the integer accuracy. / does not so you have to divide using //. You can check usins the is_integer method.
Converting to int is fast so there is no penalty converting to use as an index or a slice.

1 Like

post deleted by author

2^52 < 1e23 == True, any way ~9e15 is big enougjh for me.

Why are you polluting Python Help with something that should be in Python Ideas? This clearly isn’t a post where you are asking for help with Python.

Do you understand that all float operations have to create a float? x + 1.0 has to create a float.

All floats above 2.0**52 represent whole numbers. They certainly do not have infinite precision. They have 53 bits of precision.

Why don’t you just use Decimal? I’m pretty sure they do everything you want.


>>> from decimal import Decimal

>>> x = Decimal("1e23")

>>> format(x, '.5f')

'100000000000000000000000.00000'

1 Like

But I posted in Python Ideas. It was moved. Can some moderator explain me why?

Steven, I re-quote myself:

Decimal is a cannon for a simple task. Please re-read carefully my proposal.

I moved this topic to Python Help because it is not about enhancing Python. There is nothing here that could make Python better. The only problem is educational. The OP should learn about floating point numbers, and how they are different from integer numbers, numbers with finite decimal representations, and mathematical real numbers. I encourage other users not to write comments that do not have an educational purpose.

Sorry for not clarifying this straight away. I was exhausted.

5 Likes

Well, I think we can remove “discuss” from the URL of this forum X-D

OK, here I completely agree :joy:

I will follow your suggestion:

mod·er·at·ing
to reduce the excessiveness of; make less violent, severe, intense, or rigorous: to moderate the sharpness of one’s words.
MODERATE Definition & Usage Examples | Dictionary.com

So I exhausted you with two simple posts? Hey, I’m a big supervillain :laughing:

If you think my ideas are stupid, I’m an ignorant and I will never contribute to something in a positive way, why you read me? :roll_eyes:

  1. I proposed an internal type for creation of floats with infinite precision only for big integers, because I know that floats are different from integers, or I will not proposed that.
  2. I know what decimal is and what BigDecimal is, and I’m not proposing to use decimal everywhere.
  3. I know that floats are not reals (even if Fortran does not agree).

About my proposal

What I simply suggested is to create a “boxed” integer instead of a float for big floats that can be easily recognized by the parser as integers, like 1e23 or 100000000000000000000000.0. This integer is “boxed”, or “proxied” inside a float (a new internal type, to not augment the size of ALL floats), so it will act as a float and it will have all the trouble of a float with operations. So this is NOT decimal.

This way, 1e23 will remain a float, but internally it will be represented by a PyLong.

About my dignity

Well, I wanted to be a little ironic, but it seems it’s more appropriate a serious discussion.

This is an harsh statement without any explaining. And personally I feel it offending, if I can say.

Since any discussion with Serhiy seems useless, can someone explain me why my idea is so bad?

Not a core dev, but I think adding a brand new literal type with unfamiliar semantics should in general face an uphill climb. It’s added complexity to reason about the behavior of programs (1e23 looks like a float, but acts like an int sometimes) and has the potential to change the behavior of existing programs. If I have an application where I want to analyze floating point error and not simply live with it, a new type whose behavior is determined by context would be an unwelcome addition. (If that description is incorrect, consider that I have read two threads and that’s the best I could make of it.)

Floats and ints are broadly understood, and there are perfectly good ways to get integer values of 1e23 that will not surprise anybody who is used to working with floats and ints.

Both this thread and the original seemed to have a hypothetical scientist who needs to be protected from learning floating point error as the motivating use case, and personally I don’t find it compelling. I think education about how to construct large integers would be more valuable.


On a meta-level, I suspect that people are annoyed at how the original thread kept going after it became clear that there is no appetite among core devs to change the language in such a significant way, and now you have started another thread on the same topic. I don’t know about others, but I would hope that an Ideas thread that keeps getting longer would be a sign of broad interest and increasing precision about what the proposal would entail. Instead, the thread was driven by a couple people repeating arguments with perhaps minor variation. I can see how moderators would be frustrated with this situation.

2 Likes

Or maybe Java converts integer arguments to doubles before calling the double function Math.Pow which returns a double, like the documentation says?

Try reading your recent discussion thread that preceded this one.

We have already spent days of elapsed time and many man-hours of effort explaining why this suggestion is not workable. We’ve given you an alternative which will do what you want and exists today, but you refuse to use it. (Decimal.)

You have dismissed Decimal because you think it is too complex. To get the result you want from floats, we would need a hybrid data structure and to reimplement all the floating point functions to support this new hybrid. This will surely be more complex than Decimal, much more likely to contain bugs, and with the severe risk of surprising corner cases where this hybrid numeric type behaves in ways even more surprising than floats.

If you disagree, if you think it is so easy, go ahead and prove us wrong by implementing it. Just don’t expect other people to do it for you when they have no interest in this proposal, are sure it will be hard to do right, won’t do what you expect, and there already exists a solution that solves your problem better.

1 Like

I’m not sure which is fuel for worse nightmares: that image, or the hybrid data structure it’s describing.

I have not suggested to add a new literal type. Read below.

It’s a float. Where is it unfamiliar? Read below.

You have not understood the proposal. I’m proposing a float, that acts as a float, but has infinite precision because his value internally is an PyLong. Read below.

This is true, it can improve them, since 1e23 == 10**23 and not 1e23 == 99999999999999991611392. Read below.

I think you completely misunderstood my proposal. There’s no context and there’s no new type. I’m proposing an internal structure, not exposed, that will be created for float literals that are big integers. I quote myself, please read carefully:

########

########

If so, you should program in C, not in Python.

Well, if so, they could simply ignore the thread, not move to Help.

Because I have the ideas more clear, but evidently no one has even read seriously my post.

Yes, if it remains in Idea section and it’s not moved to Help X-D

No one have considered my frustration?

A new type, separate from float with that property, sure, decimal, mpmath or anyone’s own new class can do that. But having float matching the behavior of finite precision floating point arithmetic is useful. Two ways that come to mind are for interoperability with other languages, or when using Python for testing or reproducing computations done by software in other languages.

The “surprise” of seeing that 1e23 == 10 ** 23 is False can be solved by simply learning that 1e23 is a float, 10 and 23 are int and that ** on int outputs int.

2 Likes

Is it pluralis maiestatis?

No one refuses to use decimal. I simply think that decimal, for this simple problem, is a cannon for killing a fly.

Not too complex, but too verbose, too slow and too much inelegant for this simple task.

Please define “hybrid data structure”.

Hey, you’re a bit drastic? X-D Have you understood the new object is only internal, it will be completely transparent for the end user, and it’s always a float?

This is FUD X-D More complex than an entire library?

Of course it will contain bugs, it’s code.

The surprise will be to me to see corner cases for a float.

Is it a defiance? Should I choose the weap… the language?

I expect only to discuss my idea, not hypothetical hybrid data, natural disasters and
grasshoppers. Furthermore, I expect that an idea will be in the… well, idea section?