Windows下pip安装gmpy失败求助:编译错误及计算异常问题
问题:gmpy安装失败及gmpy2大数计算异常
1. gmpy安装失败报错
尝试在Windows下执行pip install gmpy时失败,报错信息如下:
PS C:\Users\ADMIN\Downloads> pip install gmpy Collecting gmpy Using cached gmpy-1.17.zip (147 kB) Installing build dependencies ... done Getting requirements to build wheel ... done Preparing metadata (pyproject.toml) ... done Building wheels for collected packages: gmpy Building wheel for gmpy (pyproject.toml) ... error error: subprocess-exited-with-error × Building wheel for gmpy (pyproject.toml) did not run successfully. │ exit code: 1 ╰─> [3 lines of output] gmpy.c src/gmpy.c(243): fatal error C1083: Cannot open include file: 'longintrepr.h': No such file or directory error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\bin\HostX86\x64\cl.exe' failed with exit code 2 [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for gmpy Failed to build gmpy ERROR: Could not build wheels for gmpy, which is required to install pyproject.toml-based projects
2. gmpy2大数计算异常
pip install gmpy2可正常安装,但执行大数计算时出现异常:
N = 17740803753336460891508014077951088945415214329359164945595622460861617151883658129377771074141448545977293824812472806768754107334272113784618671425945265453677763300584120796664192793654787317526905676618168560287204392207536711238413377822113265783504873957094131330620182217422910507867161033695120195691266283498385072573721376398480018719760538723050237163598524153522595496137288270407836138586188296538117138982579560625325815068701431157466298638302885600982291990551448117534677697122276691651611734934147801954625280213769902451417946572231015611006746186167211313556716518863585799128114202130873384852581 e = 65537 ct = 7617664236008252568996899627946125782926068188323112773389474654757630578865481085502759186904920518615173703165984894164411436709177950136929724052191922739861682189280802963747906815275683543148623167088950096943169566195634558711652670745197446307315888349532981492405588457559228674864147994684328968321710022127803384848143475788457274558988285904875669797926919759123645348144531804252200718312650929926931919262408975771593313266992606751663814830129337536342634243623652919127335934704778878412649409415730419077839365246227059700689395639431013008985996793686430486195007712091309878718060405038405039494286 a = sqrt(N) +1 b = (a*a) - N # 使用gmpy2时此处返回负数,无法计算p #p = a - sqrt((b)) p = 133194608574583306560585537741344865434566457335756913474195376386565743253745136529892878182973405477415063521701522490974580141634005077732157132519942995782242635825758964371685299620951981666567270659322471350406909271667819474931143113141023059424058315681431599980321513448212682539665160717948701866681 # 此结果为Ubuntu SageMath中使用gmpy得到的正确值
解决方案
针对gmpy安装失败
- 原因:gmpy是停止维护的旧版本,与Python 3.10+及Windows下的VS编译工具兼容性差,
longintrepr.h头文件在新版Python中已被移除或路径变更。 - 解决方式:
- 优先使用gmpy2并修正计算逻辑(推荐);
- 若必须使用gmpy,安装Python 3.9及以下版本,或寻找对应Python版本的预编译wheel包进行安装。
针对gmpy2计算异常
- 原因:gmpy2的
sqrt()默认返回浮点数近似值,大数场景下精度丢失,导致a = sqrt(N)+1中的a可能小于真实的整数平方根加1,进而a*a < N,使得b为负数。 - 解决方式:使用gmpy2提供的
isqrt()函数(精确整数平方根,返回不大于输入值的最大整数),修正代码如下:
import gmpy2 N = 17740803753336460891508014077951088945415214329359164945595622460861617151883658129377771074141448545977293824812472806768754107334272113784618671425945265453677763300584120796664192793654787317526905676618168560287204392207536711238413377822113265783504873957094131330620182217422910507867161033695120195691266283498385072573721376398480018719760538723050237163598524153522595496137288270407836138586188296538117138982579560625325815068701431157466298638302885600982291990551448117534677697122276691651611734934147801954625280213769902451417946572231015611006746186167211313556716518863585799128114202130873384852581 e = 65537 ct = 7617664236008252568996899627946125782926068188323112773389474654757630578865481085502759186904920518615173703165984894164411436709177950136929724052191922739861682189280802963747906815275683543148623167088950096943169566195634558711652670745197446307315888349532981492405588457559228674864147994684328968321710022127803384848143475788457274558988285904875669797926919759123645348144531804252200718312650929926931919262408975771593313266992606751663814830129337536342634243623652919127335934704778878412649409415730419077839365246227059700689395639431013008985996793686430486195007712091309878718060405038405039494286 # 用isqrt获取精确的整数平方根,再加1确保a大于sqrt(N) a = gmpy2.isqrt(N) + 1 b = (a * a) - N # 再次用isqrt计算b的整数平方根 p = a - gmpy2.isqrt(b) print(p)
- 说明:
gmpy2.isqrt()保证了计算的精确性,a会是大于sqrt(N)的最小整数,因此a*a必然大于N,b为正数,后续可正常计算得到正确的p值。
内容的提问来源于stack exchange,提问作者LilLee
相关产品推荐
相关产品推荐

