简体   繁体   English

Python四舍五入问题需要将每一位数字四舍五入

[英]Python rounding issue need to round half up every single digit

I am not sure if anyone has any bright ideas about scenarios like the following:我不确定是否有人对以下场景有任何聪明的想法:

import math
from decimal import *

def apply_precision_scale(value, precision, scale):
    # supported formats:
    # time: precision: 7, scale 4
    # amplitude: precision: 7, scale: 5
    getcontext().rounding = ROUND_HALF_UP
    
    value_int = math.trunc(value)
    rounded_input = None

    # supports negative numbers
    if precision == 7 and scale == 5:
        if (value_int >= 0 and value_int <= 99) or \
           (value_int >= -99 and value_int < 0):
             places = scale
        elif (value_int >= 100 and value_int <= 999) or \
             (value_int <= -100 and value_int >= -999):
             places = scale - 1
        elif (value_int >= 1000 and value_int <= 9999) or \
             (value_int >= -1000 and value_int >= -9999):
             places = scale - 2
        elif (value_int >= 10000 and value_int <= 99999) or \
             (value_int >= -10000 and value_int >= -99999):
             places = scale - 3          
        elif (value_int >= 100000 and value_int <= 999999) or \
             (value_int >= -100000 and value_int >= -999999):
             places = scale - 4           
        elif (value_int >= 1000000 and value_int <= 9999999) or \
             (value_int >= -1000000 and value_int >= -9999999):
             places = scale - 5
        else:
            print("Error: The value exceeds allowed precision")
            return None
    elif precision == 7 and scale == 4:
        if (value_int >= 0 and value_int <= 999) or \
           (value_int <= -100 and value_int >= -999):
             places = scale
        elif (value_int >= 1000 and value_int <= 9999) or \
             (value_int >= -1000 and value_int >= -9999):            
             places = scale - 1
        elif (value_int >= 10000 and value_int <= 99999) or \
             (value_int >= -10000 and value_int >= -99999):
             places = scale - 2
        elif (value_int >= 100000 and value_int <= 999999) or \
             (value_int >= -100000 and value_int >= -999999):
             places = scale - 3
        elif (value_int >= 1000000 and value_int <= 9999999) or \
             (value_int >= -1000000 and value_int >= -9999999):
             places = scale - 4
        else:
            print("Error: The value exceeds allowed precision")
            return None
    else:
        print("Error: Unrecognized precision and scale format")
        return None

    return float(round(Decimal(value), places))
def verify_time_increments(voltages):
    i = 2
    failures = 0
    keys = list(voltages)
    increment = 0.001953125
    increment_list = [(apply_precision_scale(increment * i, 7, 4)) for i in range(len(keys) + 1) if i != 0]
    
    for index, time in enumerate(voltages):
        try:
            expected_time = increment_list[index]
            i += 1
        except IndexError: # mismatch between number of voltages and values in increment list
            print(index)
            print(len(increment_list))

The data comes in the following format and continues until the time data points end:数据采用以下格式并持续到时间数据点结束: 在此处输入图片说明

Voltages is a dictionary in the following format [0.002:-34.54, 0.0039:-35.65, etc]电压是以下格式的字典 [0.002:-34.54, 0.0039:-35.65, etc]

For some reason I am getting errors on large numbers like this: Expected: 64.0605 Actual: 64.0606 Expected: 64.123 Actual: 64.1231出于某种原因,我在大数字上遇到这样的错误:预期:64.0605 实际:64.0606 预期:64.123 实际:64.1231

In the first example, the value I am dealing with is 64.060546875 and the second case is 64.123046785.在第一个例子中,我处理的值是 64.060546875,第二个例子是 64.123046785。 I am trying to cut them down to 4 significant digits but to round every digit up, meaning 46875 portion would be rounded to 50000, so 64.060546875 would be rounded to 64.0606.我试图将它们减少到 4 位有效数字,但要四舍五入每个数字,这意味着 46875 部分将四舍五入为 50000,因此 64.060546875 将四舍五入为 64.0606。

Sample input file: https://controlc.com/d4a3d3ba示例输入文件: https : //controlc.com/d4a3d3ba

if anyone has any bright ideas如果有人有任何好主意

How about this one?这个怎么样? Mathematically, you're actually doing the wrong thing, trying to round individual digits well past the rounding point.从数学上讲,您实际上做错了事情,试图将单个数字四舍五入远远超过舍入点。

There's a reason why rounding only checks the digit immediately after the last one you want in the answer.舍入仅在您想要的最后一个数字之后立即检查答案中的数字是有原因的。

The idea is to minimise the error, and choose the closest value based on how many digits you want.我们的想法是最小化错误,并根据您想要的位数选择最接近的值。 The closest four-decimal-place value to 64.060546875 is 64.0605 , as shown in the following table:最接近64.060546875四位小数位值为64.0605 ,如下表所示:

Value:   64.050546875   64.050546875
Round:   64.0505        64.0506
Error:    0.000046875    0.000053125

Hence the 64.0505 rounded value is a better approximation to the actual value.因此, 64.0505舍入值更接近实际值。

I guess nobody understood that I was trying to do a ROUND_UP instead of ROUND_HALF_UP.我想没有人明白我试图做一个 ROUND_UP 而不是 ROUND_HALF_UP。 This would have fixed my issue.这将解决我的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM