0

So I am trying to create a function that compares how closely two float values are the same, then the program should return the approximate value for the parts where the values are the same.

For example, when the function is given the numbers:

  1. 3.141593353533333 and 3.142222222222222 the function should return the value: 3.142
  2. 3.14222 and 3.14159 the function should return the value: 3.142
  3. 4.19999and 4.19977 the function should return the value 4.2

I've been approaching this trying to round the numbers to match. The function I made seems to work but does not always return the correct values due to rounding problems.

The function returns 4.2 for the 3rd values but 3.14 for the 1st and 2nd values.

This is because there are 2 common decimals for the 1st and 2nd values and when the rounding by 2 decimals you get 3.14 instead of 3.142

How do I get around this problem? I have a feeling I have to re-think my approach completely but I am unsure as to how and naturally adding +1 to the rounding point manually isn't an option.

Here is what I've managed to make so far:

def lukuvertailu(a, b):
    a_str = str(a).split(".") #split the given float value at the point
    b_str = str(b).split(".")
    min_len = min(len(a_str[1]), len(b_str[1])) #get the mininum amount of decimals from either value
    i = 0 #counter for the amount of matching decimals
    if (a_str[0] == b_str[0]): #check if the whole number matches.
        while i < min_len and a_str[1][i] == b_str[1][i]: #check if an decimal matches for both values.
            i += 1 #if it does, add 1 to the counter
        else:
            return "-" #if the whole number does not match, just return "-"
    num1 = round(a, i)
    num2 = round(b, i) #round the values based on the number of matching decimals
    if (num1 == num2):
        return (num1) #now the approximate value for the parts where the values are the same should be found.
TasH
  • 11
  • 1
  • 1
    Can you articulate why the result should be as you say? Why is `3.142` a good approximation but `3.14` and `3.1419` are not? – Amadan Mar 05 '23 at 02:05
  • 4
    Floating-point numbers **don't have** decimal digits, so saying that `3.141593353533333` and `3.142222222222222` "match" up until `3.142` (or anything like that) isn't really meaningful. Please read https://stackoverflow.com/questions/588004 and think more carefully about what you intend for the code to do, and then try to ask it more clearly. – Karl Knechtel Mar 05 '23 at 03:08
  • 1
    The most straightforward way to get **what you appear to want** would involve converting to string and then looking for a [common string prefix](https://stackoverflow.com/questions/6718196). – Karl Knechtel Mar 05 '23 at 03:12
  • @TasH, if `y = lukuvertailu(a, b):`, who'd you expect things to scale? Would `lukuvertailu(a*1000, b*1000)` result in `y*1000` and `lukuvertailu(a/1000, b/1000)` result in `y/1000` ? If yes, your approach will not work. If no, then the goal ignores the _float_ in _floating point_. – chux - Reinstate Monica Mar 05 '23 at 07:41
  • See comments and answers at [Floating point: how many matching significant figures?](https://stackoverflow.com/questions/62325186) (although that's talking about C, not Python). – Steve Summit Mar 05 '23 at 12:49

2 Answers2

0

Here is a simple python function to find highest approximate rounded number between two numbers:

def find_approx_round(a, b):
    a_list = []
    b_list = []
    for i in range(len(str(a).split('.')[1])):
        a_list.append(round(a, i))
    for i in range(len(str(b).split('.')[1])):
        b_list.append(round(b, i))
    try:
        return max(set(a_list).intersection(b_list))
    except ValueError:
        print('Rounded Arithmetic Mean')
        return round((a+b)/2, 10)

It is primarily intended to work with numbers like you mentioned that are close to each other, otherwise if they are far apart, it will just display the rounded arithmetic mean.

RifloSnake
  • 327
  • 1
  • 8
0

You can keep the first part of your answer for comparing the whole parts of the numbers, although it might not do what you want for comparing e.g. 123.9 and 124.1.

To compare the fractional part merely requires a simple loop:

i = 1
while round(a, i) == round(b, i) and i < 17:
    i += 1
return round(a, i-1)
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622