V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
retrocode
V2EX  ›  问与答

对于超大数 1 后 N 个 0 的整数的加减乘除,node 是否真的没办法了? 我尝试了好几个库最后都转成科学计数法了, 而 Python 就尼玛离谱, 原生支持

  •  
  •   retrocode · 2022-09-18 14:01:47 +08:00 · 2091 次点击
    这是一个创建于 795 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我找了好几个 node 库, 最后计算结果都会转成科学计数法丢失精度

    类似如下计算

    num = 35254311220000000000123400000004321432143543653465436534954325542098787651432
    num = num - 1
    print(num)
    

    而 node 就不行, 是否真的无解了? 我目前仅需要对数字做加减乘除取余计算, 有什么解决办法吗?

    18 条回复    2022-09-19 13:59:56 +08:00
    retrocode
        1
    retrocode  
    OP
       2022-09-18 14:02:52 +08:00
    一个玩具小项目, 感觉为了计算整个接口没必要, 所以我想尽量在前端解决问题, 结果啪撞坑上了
    ljsh093
        2
    ljsh093  
       2022-09-18 14:05:36 +08:00
    转字符串切一下?
    wiix
        3
    wiix  
       2022-09-18 14:07:19 +08:00
    自己做个大数运算库就行了,加减乘除还是很简单的。
    用数组,按位存储。
    Cbdy
        4
    Cbdy  
       2022-09-18 14:09:24 +08:00
    35254311220000000000123400000004321432143543653465436534954325542098787651432n - 1n

    用 BigInt
    ruxuan1306
        5
    ruxuan1306  
       2022-09-18 14:10:38 +08:00 via iPhone
    8520ccc
        6
    8520ccc  
       2022-09-18 14:11:45 +08:00 via iPhone
    decimal 就可以

    大数不可能直接用 js 的 number 来表示(只能用 string 才能完全表达)
    misdake
        7
    misdake  
       2022-09-18 14:11:50 +08:00
    原生就有 BigInt 啊
    retrocode
        8
    retrocode  
    OP
       2022-09-18 14:53:58 +08:00
    @Cbdy #4 bigint 不行 在乘除时会有丢失精度的问题 10n / 3n = 3n
    @misdake #7 bigint 不行 在乘除时会有丢失精度的问题 10n / 3n = 3n
    @ruxuan1306 #5 这个库似乎可以, 我研究下, 我之前试了 numjs 和 mathjs 都会转换成科学计数法
    lmshl
        9
    lmshl  
       2022-09-18 16:27:48 +08:00
    乘除不丢失精度,你是想要 SymPy 那样的符号计算?
    BrettD
        10
    BrettD  
       2022-09-18 16:37:24 +08:00 via iPhone
    高精度浮点数的库也有很多
    winglight2016
        11
    winglight2016  
       2022-09-18 17:30:42 +08:00
    自己实现也不难吧,提供个思路:
    1. 转二进制
    2. 用位操作实现四则运算
    himself65
        12
    himself65  
       2022-09-18 18:18:06 +08:00 via iPhone
    https://pyodide.org/ 直接前端运行 python 就行了
    ruxuan1306
        13
    ruxuan1306  
       2022-09-18 22:16:40 +08:00
    @retrocode JS 中数字实际是 float64 ,有效数字大概是 15~16 个,更大的数字运算需要换用那种用字符串模拟的大数库。

    > JavaScript 中的数字按照 IEEE 754 的标准,使用 64 位双精度浮点型来表示。其中符号位 S ,指数位 E ,尾数位 M 分别占了 1 ,11 ,52 位,并且在 ES5 规范中指出了指数位 E 的取值范围是[-1074, 971]。
    ruxuan1306
        14
    ruxuan1306  
       2022-09-18 22:20:52 +08:00
    Python 之所以任意精度,是因为 Python 原生数字就是用字节数组实现的,代价就是慢和占空间,Python 里一个一句 a = 0 ,a 就要占内存 24 字节。
    git00ll
        15
    git00ll  
       2022-09-18 23:20:16 +08:00
    math.js, 需要配置精度
    mxT52CRuqR6o5
        16
    mxT52CRuqR6o5  
       2022-09-18 23:39:51 +08:00 via Android
    你主题里的那个 case 可以用原生 bigint
    如果是想要精确计算 10/3 这种就得用 decimal.js 这类的,如果说精度达不到你的要求那就需要你手动去设置一下库的运行精度
    https://mikemcl.github.io/decimal.js/#precision
    haolongsun
        17
    haolongsun  
       2022-09-19 13:28:03 +08:00
    字符串模拟一下呗,又不是太难,小学一年级的高精度算法。
    retrocode
        18
    retrocode  
    OP
       2022-09-19 13:59:56 +08:00
    @ruxuan1306 #5 bignumber.js 可以的, 十分感谢, 我之前一直在纠结配置精度其他乱七八糟的参数, 我说一直打印不出完成数据, 直到我注意到 toFixed 函数
    @git00ll #15 之前是配置了的, 我纠结的是打印时总是打印出科学计数法, 一直没找到打印方法 orz
    @mxT52CRuqR6o5 #16 感谢分享, 这个库是可以用的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   975 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:51 · PVG 04:51 · LAX 12:51 · JFK 15:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.