如何正确使用带指数的mpf_set_str()?GMP技术问题咨询
问题根源与解决方案
你的错误核心是对GMP mpf_get_str 返回的 exp 参数含义理解偏差:
mpf_get_str返回的字符串s和指数exp满足公式:数值 = 0.s × 10^exp(0.s表示把字符串s作为小数部分,比如s="1234"就是0.1234)- 但你直接将
s和exp拼成se%ld格式,mpf_set_str会按标准科学计数法解析为 数值 = s × 10^exp,两者相差10^strlen(s)倍,自然数值不符。
看你的测试案例:
原数值 0.00000123456789 对应 mpf_get_str 返回的 s="123456789"、exp=-5,实际表示 0.123456789 ×10^-5;但你拼成的 123456789e-5 会被解析为 123456789 ×10^-5 = 1234.56789,这就是结果错误的原因。
两种可行解决方案
方案1:拼接带小数点的科学计数法字符串
直接按照 mpf_get_str 的定义格式拼接,让 mpf_set_str 正确解析:
// 替换原 sprintf 行 sprintf(real_x, "0.%se%ld", real_x, exp);
拼接后的字符串为 0.123456789e-5,mpf_set_str 解析后就是原数值 0.00000123456789。
方案2:计算正确的科学计数法指数
原数值等价于 s × 10^(exp - strlen(s)),所以计算修正后的指数再拼接:
// 替换原 sprintf 行 long new_exp = exp - strlen(real_x); sprintf(real_x, "%se%ld", real_x, new_exp);
你的案例中 strlen("123456789")=9,new_exp = -5 -9 = -14,拼接后的字符串为 123456789e-14,解析后也能得到正确数值。
修改后测试输出会与初始值一致,比如方案1的输出:
INPUT: 0.00000123456789 REAL_X: 123456789 EXP: -5 ASSIGNED REAL_X: 0.123456789e-5 NEW INPUT: 0.00000123456789 NEW REAL_X: 123456789 EXP: -5
另外你提到用 @ 替代 e,这只是GMP支持的另一种指数分隔符,和问题本身无关,核心还是指数的含义理解错误。
内容的提问来源于stack exchange,提问作者nilgirian
相关产品推荐
相关产品推荐

