[issue41598] Adding support for rounding modes to builtin round

2020-08-26 Thread marco_ocram


marco_ocram  added the comment:

"- What would you expect round(2.675, ndigits=2, mode=ROUND_HALF_UP) to give? I 
strongly suspect that Marco would expect and want a result of 2.68. But if we 
follow the existing rules for round, it's going to give 2.67."
Yes, that's right. And my second humble implementation do this but only if the 
number have a decimal part, i mean the binary approximation is managed only for 
numbers with decimal positions, not for binary distortion in huge numbers with 
a positive exponent for example. For my application is ok but not in general, 
in my fast opinion a possible solution could be translate all numbers in 
exponential decimal format and evaluate the last digit that have to be 
condidered as an approximation decimal digit before applying calculations, or 
some kind of calculations. This is the case for example of 0.4...9

- What would you expect round(2.712, ndigits=3, mode=ROUND_UP) to give? The 
binary float given by the literal 2.712 is just a touch larger than 2.712, so 
it should round up, giving 2.713. But again, I doubt that's what users will 
expect or want.  Even worse, the rounding is not idempotent: the float 2.713 is 
again a little larger than Decimal("2.713"), so it rounds up again: so if we 
round the value 2.712 twice to 3 digits using ROUND_UP, we'll get 2.714.
This is the case of 0.5...1 for example and agreee with all stated. With 
the solution proposed above in my opinion could be managed this case too, 
translating and working on decimal representation and using last digit as 
rounding digit and only for this. The user will have no more the possibility to 
use it as a significant digit to don't have the need to guess nothing. But 
pheraps this means work with strings as implemented in decimals? Sorry i don't 
know this, but i can guess.

In the end, the problem is not simple but not impossible in my opinion, it's 
right that decimals are already implemented and someone could work using them 
if needed, i don't want to impose nothing and convince noone but it's really 
funny in my opinion the only built-in rounding in a cutting-edge language as 
Python give me the banking rounding that as an not so young :-( engineer i've 
learned about now and give me results the same Microsoft in documentation index 
as misleading. I's right as i've already stated in sums reduce the rounding 
error but as i've reported the more common rounding peoples have in mind is the 
half up rounding. These are only my considerations, the choice is your, more 
experienced in the field then me.

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-22 Thread marco_ocram


marco_ocram  added the comment:

i think in your long post you have underlined among others:
1. in binary implementation of floats one bit was reserved to rounding;
2. this one bit is not enough to manage a correct rounding in a converted 
decimal base;
my considerations:
3. someone i think had evaluated deciding rounding didn't worth more 
significative digits;
4. the only solution in general can be use more digits to manage rounding in 
decimal base, not only one but more (i should think better and experiment on 
how many);
5. the problem in general cannot be solved by an implementation of rounding but 
from a revision of the implementation of floats (i have solved pretty well my 
personal need but i'm speaking in general);
6. this is not really a weak impact i think, despite it's not impossible;
7. and last, i think the current implementation could derive from historical 
reasons when we worked on 8 bits machines, not 64 bits, and one bit was of 
worth, but i may be wrong.

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-22 Thread marco_ocram


marco_ocram  added the comment:

@Vedran:
I'm sorry about my "quick-and-dirty implementations". As i've already stated 
the problem's more deep i expect, despite the second half up rounding for my 
needs now (after your observation) work well. I've verified other languages 
have the same problem with floats operations and roundings.

@Steven:
"Are you satisfied that adding a rounding mode to the built-in `round` function 
is a better solution than a series of functions in the math module? If so, I 
will change the title to reflect that."
I fully agree with the sentence and with all the content of your writings. I 
think the decimal module is excellent and can do an extraordinary work (as 
extraordinary i suppose was the work of its coders) but floats also are fine 
for common people use, i see only the rounding as main them problem. It's very 
unpleasant to round 2.8-1.3 half up and without tricks obtain a misleading 
results.
I think working on the last decimal digit if all are used the problem could be 
solved, but with a lot of study (at least for me if i have) cause one purpose 
have to be maintain good performances in addition to results always corrects.

This is only a possibility to improve the core language, i think one function 
with more common rounding ways, as in wikipedia (in gnu c i don't see just "to 
nearest, ties away from zero" or half up we discuss) or in decimals module, can 
be useful to reduce the need of individual coders implementation on a not so 
simple question cause them needs not satisfied by the round() as banking 
rounding.

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-21 Thread marco_ocram


marco_ocram  added the comment:

rndup is not correct and rnd work smooth only for numbers about < e16 until 
they have a fractional part. it's interesting but not simple.

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-21 Thread marco_ocram


marco_ocram  added the comment:

thank you very much about the hints, i've improved the code as follows.

def rnd(x, n=0):
   a = x*10**(n + 1)
   b = int(a)
   if abs(a - b) >= 0.5: b += 1 if x >= 0 else -1
   a = b/10
   b = int(a)
   if abs(a - b) >= 0.5: b += 1 if x >= 0 else -1
   return b/10**n

def rndup(x, n=0):
   a = x*10**(n + 1)
   b = int(a)
   if abs(a - b) > 0: b += 1 if x >= 0 else -1
   a = b/10
   b = int(a)
   if abs(a - b) > 0: b += 1 if x >= 0 else -1
   return b/10**n

now it manage well your cases ...

print(rnd(2.8 - 1.3), 2.8 - 1.3)
print(rnd(1.8 - 1.3), 1.8 - 1.3)
print(rnd(-2.8 + 1.3), -2.8 + 1.3)
print(rnd(-1.8 + 1.3), -1.8 + 1.3)

results ...

2.0 1.4998
1.0 0.5
-2.0 -1.4998
-1.0 -0.5

we have to define limits caused by the floating point internal representation 
but for general use in my opinion can work fine. do you see other cases where 
it cracks?

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-20 Thread marco_ocram


marco_ocram  added the comment:

print(a := rnd(rnd(2.8-1.3, 15)))
print(b := rnd(rnd(1.8-1.3, 15)))
print(a == b)

results ...

2.0
1.0
False

it's the last significative digit that have problems, we could work on the code 
to correct this and experiment if someone is interested. by the way the last 
ultra successful excel 365 - i've just tried - have the same problem. we can do 
better then ms?

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-20 Thread marco_ocram


marco_ocram  added the comment:

i want to be more clear, these could be useful.

https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/round-function
This VBA function returns something commonly referred to as bankers rounding. 
So be careful before using this function. For more predictable results, use 
Worksheet Round functions in Excel VBA.

https://docs.microsoft.com/en-us/dotnet/api/system.math.round?view=netcore-3.1
Rounding to nearest, or banker's rounding
Midpoint values are rounded to the nearest even number. For example, both 3.75 
and 3.85 round to 3.8, and both -3.75 and -3.85 round to -3.8. This form of 
rounding is represented by the MidpointRounding.ToEven enumeration member.
Rounding to nearest is the standard form of rounding used in financial and 
statistical operations. It conforms to IEEE Standard 754, section 4. When used 
in multiple rounding operations, it reduces the rounding error that is caused 
by consistently rounding midpoint values in a single direction. In some cases, 
this rounding error can be significant.

this is how work the current round() function, but if i don't need to do 
successive rounding but only adjust data i prefer...

https://docs.microsoft.com/en-us/dotnet/api/system.math.round?view=netcore-3.1
Rounding away from zero
Midpoint values are rounded to the next number away from zero. For example, 
3.75 rounds to 3.8, 3.85 rounds to 3.9, -3.75 rounds to -3.8, and -3.85 rounds 
to -3.9. This form of rounding is represented by the 
MidpointRounding.AwayFromZero enumeration member.
Rounding away from zero is the most widely known form of rounding.

i can understand in decimal the default is banking or accounting rounding and i 
can adjust the context, but in normal calculations i think will be more usefule 
the common rounding, or also the possibility to choose with an argument. i have 
simply implemented my functions, this is only for the sake of improving the 
language. cheers.

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-20 Thread marco_ocram


marco_ocram  added the comment:

revision of "if you need to realize decimal.ROUND_DOWN function trunc is 
already fine." --> "if you need to realize decimal.ROUND_DOWN function int() or 
math.trunc() are already fine."

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-20 Thread marco_ocram


marco_ocram  added the comment:

about floats ...

https://docs.python.org/3/library/functions.html#round
"if two multiples are equally close, rounding is done toward the even choice 
(so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2)"

i'm sure lots of users don't need this but a common math rounding as ...

https://docs.python.org/3/library/decimal.html#rounding-modes
decimal.ROUND_HALF_UP and as option in some cases decimal.ROUND_UP

the proposed function realize just this, for either positive and negative vals.

if you need to realize decimal.ROUND_DOWN function trunc is already fine.

i'm as mathematician have never used other roundings, i know the current round 
function work well in the accounting fiels but only there. in other languages 
sometimes the same problem (for example ms ones as old vb), really i and others 
don't know the reason.

about the revision of the standard function to accept an additional argument 
for different rounding types, for example all available for decimals, is ok for 
me, better if the default will be the normal accepted math rounding 
decimal.ROUND_HALF_UP ...

https://docs.python.org/3/library/decimal.html#decimal.BasicContext
decimal.BasicContext
This is a standard context defined by the General Decimal Arithmetic 
Specification. Precision is set to nine. Rounding is set to ROUND_HALF_UP.

about the floating point approximation in my opinion if you aren't a scientist 
you can find it pretty nice if you apply the right roundings. i think to have 
documented enough my request. take care.

--

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41598] rnd() + rndup() in math

2020-08-20 Thread marco_ocram


New submission from marco_ocram :

hello, please insert following simple but useful roundings in new lib math.

def rnd(x, n=0):
   a = x*10**n
   b = int(a)
   if abs(a - b) >= 0.5: b += 1 if x >= 0 else -1
   return b/10**n

def rndup(x, n=0):
   a = x*10**n
   b = int(a)
   if abs(a - b) > 0: b += 1 if x >= 0 else -1
   return b/10**n

thanks a lot, marco.

--
components: Library (Lib)
messages: 375695
nosy: marco_ocram
priority: normal
severity: normal
status: open
title: rnd() + rndup() in math
type: enhancement
versions: Python 3.9

___
Python tracker 
<https://bugs.python.org/issue41598>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com