我遇到了一个非常奇怪的问题。我正在尝试创建一个函数,该函数返回一个值数组,这些值包含具有特定步长的范围(例如您可能在绘图的轴上找到)。而不仅仅是使用np.arange(min,max,step)
,我想要更好地围绕步长的东西。这是我试过的:
def get_decade(value):
return pow(10,math.floor(math.log10(value)))
def get_steparray(min,max,delta):
delta_step = float(get_decade(delta))
next = math.floor(min/delta_step)*delta_step
print next
array = [next]
while next < max:
next = int((next+delta_step)/delta_step)*delta_step
print next
array.append(next)
print array
print array
return array
打印声明在那里帮助我弄清楚发生了什么。这是我尝试运行它:
print get_steparray(1.032,1.431,0.1)
由此,我期待数组最终为[1.0,1.1,1.2,1.3,1.4,1.5]
以下是我从函数中获得的内容:
1.0
1.1
[1.0, 1.1]
1.2
[1.0, 1.1, 1.2000000000000002]
1.3
[1.0, 1.1, 1.2000000000000002, 1.3]
1.4
[1.0, 1.1, 1.2000000000000002, 1.3, 1.4000000000000001]
1.5
[1.0, 1.1, 1.2000000000000002, 1.3, 1.4000000000000001, 1.5]
[1.0, 1.1, 1.2000000000000002, 1.3, 1.4000000000000001, 1.5]
正如您所看到的,其中一些有效,而另一些则添加了额外的小数。
任何人都有任何想法可能导致这个?感谢您提供的任何见解。或者,如果有人知道创建这样一个数组的更好,更实用的方法,我会很高兴。也许我应该坚持使用np.arange并调整最大/最小/步长值?
(是的,我知道我的代码并不是最干净的。上面的函数开始时更清晰,但我添加了一些不必要的功能,试图让它工作。)
编辑:虽然我感谢所有人的深刻见解,但我仍然不确定他们是否完全解决了我的问题。正如在打印输出中可见的那样,当作为孤立的浮动类型时,每个值都以足够的精度存储。但是当它们被添加到数组中时,它们才会改变精度。一般来说,我非常清楚浮点问题,但对浮点数和数组之间的具体差异感到好奇。我想知道数组是否可以将值存储在比单个值更低的位数中。
话虽如此,我认为在使用时更多地关注格式化的建议是我最终会做的。
谢谢!
答案 0 :(得分:1)
这是一个典型的浮点算术问题。
我将在此处发布Python documentation for floating-point arithmetic issues and limitations的摘录,但大多数语言都是如此:
浮点数在计算机硬件中表示为基数2 (二元)分数。例如,小数部分
0.125
的值为
1/10 + 2/100 + 5/1000
,二进制的方式相同 分数0.001
的值为
0/2 + 0/4 + 1/8
。这两个部分相同 值,唯一真正的区别是第一个写入 基数为10的分数表示法,第二个为基数2。不幸的是,大多数小数部分不能完全表示为 二进制分数。结果是,一般来说,十进制 您输入的浮点数仅由二进制近似 实际存储在机器中的浮点数。
这个问题最初在基地10中更容易理解。考虑一下 分数
1/3
。您可以将其近似为基数10分数:0.3
或者更好,
0.33
或者更好,
0.333
等等。无论你愿意记下多少位数,都可以 结果永远不会完全
1/3
,但会越来越好 近似1/3
。
<小时/>
现在你知道了为什么,这里 你可以解决这个问题。
如果您不需要所有这些精确度(或者就此而言......所有这些不精确),您可以随时:
round
内置