Python Xlrd浮动进动问题

时间:2014-06-23 14:52:26

标签: python floating-point xlrd

我正在尝试使用xlrd模块将excel(xlsx)文件中的数据转储到文本文件中,并且浮动进程存在问题。

已找到一些类似问题的帖子,在16位十进制数字的最后一位丢失岁差。

以下是从xlsx复制的数据:

VALUE;DATA
1.01    HELLO
2.11    1/1/2014
3.21    ONE
4.31    1/1/2014 12:14
5.441   $10 
6.241   TWO
77.11   Zulfi
8.11    99
9.11    99.999
10.11   0

以下是我从xlrd获得的信息:

 1.01|'HELLO'
2.1099999999999999|'2014-01-01 00:00:00.000000'
3.21|'ONE'
4.3099999999999996|'2014-01-01 12:14:00.000000'
5.4409999999999998|10.0
6.2409999999999997|'TWO'
77.109999999999999|'Zulfi'
8.1099999999999994|99.0
9.1099999999999994|99.998999999999995
10.109999999999999|0.0
  1. " 2.11"已成为" 2.1099999999999999"和" 4.31"已成为" 4.3099999999999996"等...
  2. " $ 10#34;已成为" 10"
  3. 日期值看起来有点不同(我理解这个,我得到了我编码的内容)
  4. 我确实理解浮游物的一些奥秘,其中有可能失去进动,因为小数点后面有太多数字的值,但这里我只有两位数。

    我通过与开源ETL工具" Pentaho"的比较来测试输出。 (用java编写)可以读取/写入excel文件,这个工具似乎没有问题,因为它们出现在xlsx文件中(这些字段被读作字符串和长度为30且进动数为20的数字)

    以下是Pentaho的内容

    VALUE;DATA
     1.01;HELLO
     2.11;2014/01/01 00:00:00.000
     3.21;ONE
     4.31;2014/01/01 12:14:00.000
     5.441; 10.0
     6.241;TWO
     77.11;Zulfi
     8.11; 99.0
     9.11; 99.999
     10.11; 0.0
    

    以下是我的python代码:

    for rownum in xrange(sh.nrows):
        for colnum in xrange(sh.ncols):
            cell_obj = sh.cell(rownum,colnum)
            cell_val=sh.cell_value(rownum,colnum)
            if cell_obj.ctype == xlrd.XL_CELL_DATE:
                year, month, day, hour, minute, second = xlrd.xldate_as_tuple(cell_val, wb.datemode)
                py_date = datetime.datetime(year, month, day, hour, minute, second).strftime("%Y-%m-%d %H:%M:%S.%f")
                cell_val = py_date
            if (colnum==0):
                row_values=repr(cell_val)
            else :
                row_values=row_values+fdel+repr(cell_val)
        if (((row_values).find("\\n"))>-1):
            NLFlag=1
        file_output.write((row_values).replace('\\n','') + "\n")
        row_values=''
    file_output.close()
    

    对此的任何帮助都非常感谢。

    由于

1 个答案:

答案 0 :(得分:0)

Floats,又名双精度实数,只有大约16个十进制数字的精度。当分数的形式为2 ^ -n时,它们只能精确地表示小数分数,因此是1/8或1/1024的倍数。所有其他小数可能不准确。

如果您打印出没有进一步说明的浮动,您将获得系统尽力表示十进制的二进制分数,所以2.099999999999等而不是2.1。但是,如果您知道浮点数不超过(例如)3个十进制数字,那么您可以强制它们在输出上舍入,例如通过使用字符串格式函数

file_output.write('{0:.3f}'.format(f_num))

将正确向下舍入输出f_num并用零填充到3个位置

我猜想默认情况下,xlrd库会解释任何可以作为float的字段。应该有一个开关强制所有的读取都是字符串,在这种情况下,你打印出来的内容就是你所读的内容。