Can I suggest a way to look at it, Grant? In base 10, we represent all numbers as the (possibly infinite) sum of ten raised to some integral power.
123 is 3 times 1 (ten to the zero power) plus 2 times 10 (ten to the one power) plus 1 times 100 (ten to the two power) 123.456 just extends this with 4 times 1/10 (ten to the minus one power) plus 5 times 1/100 (10**-2) plus 6 time 1/1000 (10**-3) In binary, all the powers are not powers of 10 but powers of two. So IF you wrote something like 111 it means 1 times 1 plus 1 times 2 plus 1 times 4 or 7. A zero anywhere just skips a 2 to that power. If you added a decimal point to make 111.111 the latter part would be 1/2 plus 1/4 plus 1/8 or 7/8 which combined might be 7 and 7/8. So any fractions of the form something over 2**N can be made easily and almost everything else cannot be made in finite stretches. How would you make 2/3 or 3 /10? But the opposite is something true. In decimal, to make the above it becomes 7.875 and to make other fractions of the kind, you need more and more As it happens, all such base-2 compatible streams can be made because each is in some sense a divide by two. 7/16 = 1/2 * .875 = .4375 7/32 = 1/2 * .4375 = .21875 and so on. But this ability is a special case artifact caused by a terminal digit 5 always being able to be divided in tow to make a 25 a unit longer and then again and again. Note 2 and 5 are factors of 10. In the more general case, this fails. In base 7, 3/7 is written easily as 0.3 but the same fraction in decimal is a repeating copy of .428571... which never terminates. A number like 3/7 + 4/49 + 5/343 generally cannot be written in base 7 but the opposite is also true that only a approximation of numbers in base 2 or base 10 can ever be written. I am, of course, talking about the part to the right of the decimal. Integers to the left can be written in any base. It is fractional parts that can end up being nonrepeating. What about pi and e and the square root of 2? I suspect all of them have an infinite sequence with no real repetition (over long enough stretches) in any base! I mean an integer base, of course. The constant e in base e is just 1. As has been hammered home, computers have generally always dealt in one or more combined on/off or Boolean idea so deep down they tend to have binary circuits. At one point, programmers sometimes used base 8, octal, to group three binary digits together as in setting flags for a file's permissions, may use 01, 02 and 04 to be OR'ed with the current value to turn on read/write/execute bits, or a combination like 7 (1+2+4) to set all of them at once. And, again, for some purposes, base 16 (hexadecimal) is often used with numerals extended to include a-f to represent a nibble or half byte, as in some programs that let you set colors or whatever. But they are just a convenience as ultimately they are used as binary for most purposes. In high school, for a while, and just for fun, I annoyed one teacher by doing much of my math in base 32 leaving them very perplexed as to how I got the answers right. As far as I know, nobody seriously uses any bases not already a power of two even for intermediate steps, outside of some interesting stuff in number theory. I think there have been attempts to use a decimal representation in some accounting packages or database applications that allow any decimal numbers to be faithfully represented and used in calculations. Generally this is not a very efficient process but it can handle 0.3 albeit still have no way to deal with transcendental numbers. As such, since this is a Python Forum let me add you can get limited support for some of this using the decimal module: https://www.askpython.com/python-modules/python-decimal-module But I doubt Python can be said to do things worse than just about any other computer language when storing and using floating point. As hammered in repeatedly, it is doing whatever is allowed in binary and many things just cannot easily or at all be done in binary. Let me leave you with Egyptian mathematics. Their use of fractions, WAY BACK WHEN, only had the concept of a reciprocal of an integer. As in for any integer N, there was a fraction of 1/N. They had a concept of 1/3 but not of 2/3 or 4/9. So they added reciprocals to make any more complex fractions. To make 2/3 they added 1/2 plus 1/6 for example. Since they were not stuck with any one base, all kinds of such combined fractions could be done but of course the square root of 2 or pi were a bit beyond them and for similar reasons. https://en.wikipedia.org/wiki/Egyptian_fraction My point is there are many ways humans can choose to play with numbers and not all of them can easily do the same thing. Roman Numerals were (and remain) a horror to do much mathematics with and especially when they play games based on whether a symbol like X is to the left or right of another like C as XC is 90 and CX is 110. To do programming learn the rules that only what can be represented in binary has a chance to ... -----Original Message----- From: Python-list <python-list-bounces+avigross=verizon....@python.org> On Behalf Of Grant Edwards Sent: Saturday, November 20, 2021 5:24 PM To: python-list@python.org Subject: Re: Unexpected behaviour of math.floor, round and int functions (rounding) On 2021-11-20, Ben Bacarisse <ben.use...@bsb.me.uk> wrote: > You seem to be agreeing with me. It's the floating point part that is > the issue, not the base itself. No, it's the base. Floating point can't represent 3/10 _because_ it's base 2 floating point. Floating point in base 10 doesn't have any problem representing 3/10. -- Grant -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list