浮点数中的固定位数 [英] Fixed digits number in floats

查看:130
本文介绍了浮点数中的固定位数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 SE 上阅读了很多关于此的讨论,但仍然找不到合适的.

I read a lot of discussion about this on SE, but still can't find the right one.

我想用相同的位数绘制一些不同长度的数字.

I want to plot some numbers, of various lengths, with the same number of digits.

例如我有:12.3456781.2345678.现在,因为我必须用他们的错误来绘制它们,我希望每个都有不同的格式,以便它们很重要.

For example I have: 12.345678, 1.2345678. Now, since I have to plot them with their error, I want that each one has a different format, in order that they are significant.

所以,我想用可变的小数位数来绘制它们.就我而言,绘制 23.45678+/-1.23456 没有任何意义,但更好的是 23.4+/-1.2.另一方面,我需要 1.234567+/-0.034567 变成 1.23+/-0.03.

So, I want to plot them with a variable number of decimals. In my case, it makes no sense to plot 23.45678+/-1.23456 but better is 23.4+/-1.2. On the other hand, I need that 1.234567+/-0.034567 becomes 1.23+/-0.03.

所以,比方说,我想绘制所有具有固定宽度的数字,总共可以是 3 位数字加上逗号.我应该使用类似 '%1.1f' %num 的东西,但我找不到正确的方法.我该怎么做?

So, let's say, I want to plot all the numbers with a fixed width, could be 3 digits in total plus the comma. I should use something like '%1.1f' %num, but I can't find the right way. How can I do that?

推荐答案

我建议定义一个类来解释字符串格式化程序以提供您想要的内容.
在该类中,您确定浮点数的整数部分的长度,并使用它来定义适当的字符串格式.
简而言之,如果您的输入是 12.345(因为小数点分隔符前有两位数字)和 {:4.2f} 如果您输入它 1.2345 (因为您在小数点分隔符之前只有一位数字).总位数(在本例中为 4)作为输入提供.
新的格式化程序是: {:nQ} 其中 n 是总位数(因此在上面的示例中,您需要指定 {:4Q}得到你想要的输出.
代码如下:

I recommend defining a class that interprets a string formatter to give what you want.
Inside that class, you determine the length of the integer portion of your float and use that to define the appropriate string format.
In a nutshell, the class creates a formatter like '{:4.1f}' if your input is 12.345 (because you have two digits before the decimal separator) and {:4.2f} if your input it 1.2345 (because you have only one digit before the decimal separator). The total number of digits (4in this example) is provided as an input.
The new formatter is: {:nQ} where n is the total number of digits (so in the above example, you'd specify {:4Q}to get the output you want.
Here's the code:

import math

class IntegerBasedFloat(float):
    def __format__(self, spec):
        value = float(self)

        # apply the following only, if the specifier ends in Q
        # otherwise, you maintain the original float format
        if spec.endswith('Q'):
            # split the provided float into the decimal 
            # and integer portion (for this math is required):
            DEC, INT = math.modf(value)

            # determine the length of the integer portion:
            LEN = len(str(abs(int(INT))))

            # calculate the number of available decimals 
            # based on the overall length
            # the -1 is required because the separator 
            # requires one digit
            DECIMALS = int(spec[-2]) - LEN - 1

            if DECIMALS < 0:
                print 'Number too large for specified format'
            else:
                # create the corresponding float formatter
                # that can be evaluated as usual:
                spec = spec[-2] + '.' + str(DECIMALS) + 'f'

        return format(value, spec)

DATA = [12.345, 2.3456, 345.6789]

print '{:4Q}'.format(IntegerBasedFloat(DATA[0]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[1]))
print '{:4Q}'.format(IntegerBasedFloat(DATA[2]))
print 'This is a "custom" float: {:5Q} and a "regular" float: {:5.3f}'.format(IntegerBasedFloat(12.3456),12.3456)

输出应该是:

12.3
2.35
 346
This is a "custom" float: 12.35 and a "regular" float: 12.346

<小时>

这个答案的灵感来自:- 将数字拆分为整数和小数部分在python中
- 为字符串格式添加自定义转换类型

这篇关于浮点数中的固定位数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆