Python等价于C strtod

2024-09-30 02:30:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在研究将C++程序的部分转换成Python,但是替换C函数strtod有一些困难。 我正在研究的字符串由简单的数学公式组成,例如“KM/1000.0”。问题是常量和数字是混合的,因此我无法使用float()。

如何编写一个Python函数来模拟strtod,它同时返回转换后的数字和下一个字符的位置?


Tags: 函数字符串程序数字float数学公式字符常量
3条回答

我不知道任何现有的函数可以做到这一点。在

但是,使用正则表达式编写一个非常容易:

import re

# returns (float,endpos)
def strtod(s, pos):
  m = re.match(r'[+-]?\d*[.]?\d*(?:[eE][+-]?\d+)?', s[pos:])
  if m.group(0) == '': raise ValueError('bad float: %s' % s[pos:])
  return float(m.group(0)), pos + m.end()

print strtod('(a+2.0)/1e-1', 3)
print strtod('(a+2.0)/1e-1', 8)

一个更好的整体方法可能是构建一个lexical scanner,它首先将表达式标记化,然后使用一系列标记,而不是直接使用字符串(或者确实是全力以赴地构建一个yacc风格的解析器)。在

您可以创建一个简单的C strtod包装:

#include <stdlib.h>

double strtod_wrap(const char *nptr, char **endptr)
{
   return strtod(nptr, endptr);
}

编译时使用:

^{pr2}$

(如果使用64位Python,编译器也必须是64位的)

并使用python中的ctypes调用它(linux:在lib目标中将.dll改为{},在下面的代码中,这在Windows上进行了测试):

import ctypes

_strtod = ctypes.CDLL('libstrtod.dll')
_strtod.strtod_wrap.argtypes = (ctypes.c_char_p, ctypes.POINTER(ctypes.c_char_p))
_strtod.strtod_wrap.restype = ctypes.c_double

def strtod(s):
    p = ctypes.c_char_p(0)
    s = ctypes.create_string_buffer(s.encode('utf-8'))
    result = _strtod.strtod_wrap(s, ctypes.byref(p))
    return result,ctypes.string_at(p)

print(strtod("12.5hello"))

印刷品:

(12.5, b'hello')

(这并不像看上去那么难,因为我10分钟前就学会了怎么做)

关于ctypes的有用问答

你自己分析这个数字。在

递归下降解析器对于这种输入非常容易。 首先写一个语法:

float ::= ipart ('.' fpart)* ('e' exp)*
ipart ::= digit+
fpart ::= digit+
exp   ::= ('+'|'-') digit+
digit = ['0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9']

现在把这个语法转换成函数应该很简单。。。在

相关问题 更多 >

    热门问题