IDL中数字的精度问题:需要定义一个浮点型数组,如【40411323.654,42583654.878】并进行运算。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IDL中数字的精度问题:需要定义一个浮点型数组,如【40411323.654,42583654.878】并进行运算。相关的知识,希望对你有一定的参考价值。

但IDL只自动保留8位,怎么办呢?定义的是dblarray类型的数组,为什么出现这种情况?

可以这样定义
a=dlbarr(2)
a[0] = 40411323.654d
a[1] = 42583654.878d
或者直接 a = [40411323.654d,42583654.878d]
如果不写d,小数默认是float类型,就会损失精度
对于你这样的情况,IDL先解析40411323.654成float类型,就是40411324.000,再强制转换到double,前一步已经损失精度了
可以使用print,a,format='(f0.3)'查看小数点后三位有效数字追问

还是不行哦

追答

你直接print是看不全的,print,a,format='(f0.3)'查看小数点后三位有效数字,再试试吧
或者print,a,format='(d)',你会发现很多不一样的东西

追问

还是不行啊·~·怎么办呢?还有没有别的方法?是需要运算的 。、。。

追答

你是要printf写入到文件里?printf也有format可以设置
有点搞不清楚你的需求,数值那么设置应该没错的

追问

恩 是要写入文件的,不过要先经过运算 我给的截图是用read读取的数字,然后又print的。在运算的时候 还是自动把后面的部分给省了 只留了8位。。。

追答

你read读取完,用print显示数值对不对?
运算完就不对了?
把每步的值都print出来看看
最好那块读取运算的代码也贴一下

参考技术A 双精度的输出显示是会自动截取。你在输出时用Format格式看看

Python数字型整理(整型布尔型浮点型复数操作符内建函数与工厂函数控制数字精度)

数字提供了标量贮存和直接访问。它是不可更改类型,也就是说变更数字的值会生成新的对象。这个过程对程序员和用户是透明的。

Python支持多种数字类型:整型、布尔型、双精度浮点型和复数。

整型

Python里面的整型默认就能表示很大的整型。可以是十进制、八进制、十六进制。八进制以0o开头(第一个字符是数字0,第二个字符是字母o或O),十六进制以0x开头(第一个字符是数字0,第二个字符是字母x或X)。十进制在Python3.x版本中不支持后面加“l”或“L”。

print(156487)
print(0o156)
print(0x178)

布尔型

布尔类型是只有两个值的整型:True和False。

双精度浮点型

浮点型值通常都有一个小数点和一个可选的后缀e(小写或者大写,表示科学计数法)。在e和指数之间可以用正(+)或负(-)表示整数的正负(正数的话可以省略符号)。

print(0.0)
print(-777.)
print(1.6)
print(-5.55555555555545)
print(96e3)
print(4.2E-10)
print(6.022e23)

复数

(不重要)规定(现阶段复数用得少,这些规定没那么必要了):

  • 虚数不能单独存在,它们总是和一个值为0.0的实数部分一起来构成一个复数(现版本没有这个要求)
  • 复数由实数部分(可选)和虚数部分构成
  • 表示虚数的语法:real(可选) + imag j
  • 实数部分和虚数部分都是浮点型(复数0表示为0.0+0.0j,上机验证0j也对)
  • 虚数部分必须有后缀j或J
print(64.454+5j)
print(6.45-8.5j)
print(1.23e-045+6.7e+089j)
print(-1.23-897j)

复数的内建属性

操作符

混合模式操作符

Python使用数字类型强制转换的方法来解决数字类型不一致的问题,也就是说它会强制将一个操作数转换为同另一个操作数相同的数据类型。这种操作不是随意进行的,它遵循以下基本规则。

首先,如果两个操作数都是同一种数据类型,没有必要进行类型转换。仅当两个操作数类型不一致时, Python才会去检查一个操作数是否可以转换为另一类型的操作数。如果可以,转换它并返回转换结果。由于某些转换是不可能的,比如将一个复数转换为非复数类型,将一个浮点型转换为整型等,因此转换过程必须遵守几个规则。

要将一个整型转换为浮点型,只要在整型后面加个“0”就可以了。要将一个非复数转换为复数,则只需要要加上一个“0”的虚数部分。这些类型转换的基本原则是:整型转换为浮点型,非复数转换为复数。在 Python语言参考中这样描述 coerce方法

  1. 如果有一个操作数是复数,另一个操作数被转换为复数;否则,如果有一个操作数是浮点型,另一个操作数被转换为浮点型;否则,如果有一个操作数是长整型,则另一个操作数被转换为长整型;
  2. 否则,两者必然都是普通整型,无须类型转换。

即复数>浮点数>整型>布尔型

标准类型操作符

对象值的比较

所有的内建类型均支持比较运算,比较运算返回布尔值True或False。

不讨论复数。

对象身份比较

布尔类型

print(5.2==5.2)
print(-719>=833)
print(2<3<4)
print(77>66==66) #等价于(77>66)and(66==66)
print(0.<-90.4<55.3e2!=3<181)#短路
print((-1<1)or(1<-1))

算术操作符

说明:

1.expr1**expr2 是幂运算,幂运算操作符和一元操作符之间的优先级关系比较特别:幂运算操作符**比其左侧操作数的一元操作符优先级高,比其右侧操作数的一元操作符的优先级低。 如下例:

print(3**2)
print(-3**2)
print((-3)**2)
print(4.0**-1.0)
print(4**-1) #并不会报错

2. expr1%expr2是取模运算,其中浮点数取余规则是商取小于等于精确值最大的整型的乘积只差,即x-(math.floor(x/y)*y)。对于复数不适用。

print(5.3%2.5)
print(6.8%2.7)

print((3+2j)%6)

3. expr1/expr2与expr1//expr2区别:expr1/expr2得到正常的结果,expr1//expr2得到向下取整的结果。

print(3/2)
print(3//2)

位操作符(只适用于整型)

Python整型支持标准位运算:取反(~),按位与(&)、或(|)和异或(^),以及左移(<<)和右移(>>)。 Python这样处理位运算。

  1. 负数会被当成正数的2进制补码处理。
  2. 左移和右移N位等同于无溢出检查的2的N次幂运算:2**N。
  3. 对长整型来说,位操作符使用一种经修改的2进制补码形式,使得符号位可以无限向左扩展。

取反(~)运算的优先级与数字单目操作符相同,是所有位操作符中优先级最高的一个。左移和右移运算的优先级次之,但低于加减法运算。与、或、异或运算优先级最低。所有位操作符按优先级高低列在表5.4

注:手动计算的方法是把这些整型转化成二进制数,再进行取反、左移、右移、按位与(同为1时为1,其他为0)、按位或(同为0时为0,其他为1)、异或(相同为0,不同为1)

print(30&45)
print(30|45)
print(45&60)
print(45|60)
print(~30)
print(~45)
print(45<<1)
print(60>>2)
print(30^45)

内建函数与工厂函数

标准类型函数

注意:Python3已经没有cmp()函数了。

数字类型函数

转换工厂函数(重点介绍int())

注意:Python 3版本已经不支持long()了。

说明:
int(x, base=10)   返回值一定都是十进制整数。
x 有两种:str / int。

1、若 x 为纯数字,则不能有 base 参数,否则报错;其作用为对入参 x 取整

print(int(4.2555555))
print(int(4.2555555555,base=8))

2、若 x 为 str,且str必须是整数,则 base 可略可有。

base 存在时,视 x 为 base 类型数字,并将其转换为 10 进制数字。

若 x 不符合 base 规则,则报错。如:

print(int('9',2)) #报错,因为2进制无9

print('9') #默认十进制

print(int('3.14',8)) #均报错,str须为整数
print('1.2')

print(int('1001',2)) #二进制
print(int('123',8)) #八进制
print(int('a',16)) #十六进制

功能函数 abs() divmod()  pow() round()

注意:Python 3已经舍弃了coerce()。

说明:

abs()返回给定参数的绝对值。

divmod()内建函数把除法和取余运算结合起来,返回一个包含商和余数的元组。对整型来说,它的返回值就是向下取整和取余操作的结果。对浮点型来说,返回的商部分是 math. floor(numl/mum2)。

print(divmod(10,3))
print(divmod(2.5,10))

pow()和双星号(**)操作符都可以进行指数运算。不过二者的区别并不仅仅在于一个是操作符,一个是内建函数。pow()还接受第三个可选的参数,即一个余数参数,如果有这个参数,pow()先进行指数运算,然后将运算结果和第三个参数进行取余运算。这个特性主要用于密码运算,并且比 pow(x, y)%z性能更好。

print(pow(2,5))
print(pow(5,2))
print(pow(2,5,2))

round()用于对浮点型进行四舍五入运算。它有一个可选的小数位数参数。如果不提供小数位参数,它返回与第一个参数最接近的整型(但仍然是浮点类型)。第二个参数告诉 round函数将结果精确到小数点后指定位数。

print(round(3.45))
print(round(3.49999999))
print(round(3.49999999,1))
print(round(3.3655,2))
print(round(3.5))

int()、math.floor()、math.ceil()、round()区别

  • 函数int()直接截去小数部分
  • 函数 math.floor()得到小于等于原数的最小整数
  • 函数 math.ceil()得到大于等于原数的最小整数
  • 函数 round()得到最接近原数的整型(四舍五入)
import math
print(int(0.2),end=' ')
print(math.floor(0.2),end=' ')
print(round(0.2))

print(int(0.7),end=' ')
print(math.floor(0.7),end=' ')
print(round(0.7))

print(int(-0.2),end=' ')
print(math.floor(-0.2),end=' ')
print(round(-0.2))

print(int(-0.7),end=' ')
print(math.floor(-0.7),end=' ')
print(round(-0.7))

仅用于整型的函数

进制转换函数

Python提供了两个内建函数来返回字符串表示的八进制和十六进制整型,它们分别是oct()和hex()。它们都接受一个整型(任意进制的)对象,并返回一个对应值的字符串对象。下面是几个示例。

print(hex(255))
print(hex(65535*2))
print(oct(255))
print(oct(65535*2))

ASCII转换函数

Python也提供了ASCII(美国标准信息交换码)码与其序列值之间的转换函数。每个字符对应一个唯一的整型(0~255)。对所有使用ASCI表的计算机来说,这个数值是不变的。这保证了不同系统之间程序行为的一致性。函数chr()接受一个单字节整型值,返回一个字符串,其值为对应的字符。函数ord()则相反,它接受一个字符,返回其对应的整型值。

print(ord('a'))
print(ord('A'))
print(chr(97))
print(chr(65))

控制数字精度

round()内置方法

round()不是简单的四舍五入(银行家舍入,四舍六入五双留),第二个参数可以选择保留几位小数。

round()如果只有一个数作为参数,不指定位数的时候,返回的是一个整数,而且是最靠近的整数(这点上类似四舍五入)。但是当出现.5的时候,两边的距离都一样,round()取靠近的偶数,这就是为什么round(2.5) = 2。当指定取舍的小数点位数的时候,一般情况也是使用四舍五入的规则,但是碰到.5的这样情况,如果要取舍的位数前的数是奇数,则直接舍弃,如果偶数则向上取舍。

from decimal import *
print(round(2.635,2))
print(round(2.535,2))
print(round(2.645,2))
print(round(2.655,2))
print(round(2.665,2))
print(round(2.675,2))
print(round(1.35,1))
print(round(1.65,1))
print(Decimal.from_float(2.635))
print(Decimal.from_float(1.35))
print(Decimal.from_float(1.65))

from decimal import *
print(Decimal.from_float(3.1250))
print(Decimal.from_float(9.8350))
print(Decimal.from_float(3.2250))
print(Decimal.from_float(9.3750))
print(round(3.1250,2))
print(round(9.8350,2))
print(round(3.2250,2))
print(round(9.3750,2))

使用格式化

效果和round()一样。

a = ("%.2f" % 2.637)
print(a)

更多Python框架梳理,请参考: 【Python学习】Python最全总结

 有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。

以上是关于IDL中数字的精度问题:需要定义一个浮点型数组,如【40411323.654,42583654.878】并进行运算。的主要内容,如果未能解决你的问题,请参考以下文章

关于浮点型误差的解决方法

c复习过程随笔二

浮点型数据转存到字符串中(转)

C 语言中双精度浮点型精度怎样保留位数

什么是浮点型数据

精度浮点型数据精确到了几位小数呢?