草庐IT

Python 扩展 - 有效地构造和检查大整数

coder 2023-08-18 原文

我有一个本地库,其自然接口(interface)将涉及传递可能很大的数字。我预计大约一半是 < 32="" 位;另一个四分之一="">< 64="" 位;接下来的八分之一="">< 128="" 位="" -="">

如果我可以将值限制为适合单个寄存器,则 PyLong_FromUnsignedLongLong() 和 PyLong_AsUnsignedLongLong() 将是合适的。

PyLong_FromString() 克服了这个问题——但是需要中间表示的代价是不受欢迎的。 _PyLong_FromByteArray() 和 _PyLong_AsByteArray() 减轻了这个成本(通过简化这个中间表示)但是前导下划线让我想知道这是否会导致可移植性问题。

在 longintrepr.h 中,我发现了 struct _longobject...这暗示它可能是一种直接与内部表示交互的方式...尽管缺乏关于此结构的详细文档仍然是一个障碍。

什么方法可以在 Python 和库之间实现最佳吞吐量?是否有我忽略的文档?

最佳答案

下划线前缀在 C API 中的含义与在普通 Python 中的含义大致相同:“此函数是一个可能会更改的实现细节,因此使用它时请注意自己”。不禁止您使用此类功能,如果这是实现特定目标的唯一方法(例如,在您的案例中显着提高效率),那么只要您意识到危险,就可以使用 API。

如果 _PyLong_FromByteArray API 是真正私有(private)的,它将是一个static 函数,不会在 longobject.h 中完整记录和导出>。事实上,Tim Peters(著名的 Python 核心开发人员)明确 blesses its use :

[Dan Christensen]

My student and I are writing a C extension that produces a large integer in binary which we'd like to convert to a python long. The number of bits can be a lot more than 32 or even 64. My student found the function _PyLong_FromByteArray in longobject.h which is exactly what we need, but the leading underscore makes me wary. Is it safe to use this function?

Python 在内部使用它,所以最好是 ;-)

Will it continue to exist in future versions of python?

没有保证,这就是为什么它有一个前导下划线:它不是 官方支持的,外部记录的,广告的一部分 Python/C API。碰巧我添加了那个功能,因为 Python 在内部需要某种形式的功能 不同的 C 模块。使其成为 Python/C API 的官方部分 本来会有更多的工作(我没有时间),并且 创造了一个永恒的新维护负担(我不热衷于 不管;-)).

在实践中很少有人接触Python的这部分实现,所以 我不/期望/它会在未来几年消失,甚至改变。 我能立即想到的最大的不安全感是有人可能 发起一场运动以制作其他一些字节数组 <-> 长接口(interface) “官方”基于表示负整数的不同方式。 但即便如此,我仍希望当前的非官方功能能够保留, 因为 256 的补码表示对于 struct 模块的“q”格式,以及 pickle 模块的 protocol=2 长序列化格式。

Or is there some other method we should use?

没有。这就是为什么发明这些函数以 ;-) 开头的原因

这是文档(来自 Python 3.2.1):

/* _PyLong_FromByteArray:  View the n unsigned bytes as a binary integer in
   base 256, and return a Python long with the same numeric value.
   If n is 0, the integer is 0.  Else:
   If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
   else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
   LSB.
   If is_signed is 0/false, view the bytes as a non-negative integer.
   If is_signed is 1/true, view the bytes as a 2's-complement integer,
   non-negative if bit 0x80 of the MSB is clear, negative if set.
   Error returns:
   + Return NULL with the appropriate exception set if there's not
     enough memory to create the Python long.
*/
PyAPI_FUNC(PyObject *) _PyLong_FromByteArray(
    const unsigned char* bytes, size_t n,
    int little_endian, int is_signed);

它是一个“下划线前缀”API 的主要原因是因为它依赖于 Python long 的实现,作为以二次幂为基数的单词数组。这不太可能改变,但由于您在此基础上实现了一个 API,因此您可以使调用者免受稍后 Python API 更改的影响。

关于Python 扩展 - 有效地构造和检查大整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18290507/

有关Python 扩展 - 有效地构造和检查大整数的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  3. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  4. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  5. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  6. ruby - 如何进行排列以有效地定制输出 - 2

    这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][

  7. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  8. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  9. ruby - 检查日期是否在过去 7 天内 - 2

    我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/

  10. c - mkmf 在编译 C 扩展时忽略子文件夹中的文件 - 2

    我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。

随机推荐