博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我曾在极度愤怒的情况下,完成几百位的乘法运算
阅读量:4196 次
发布时间:2019-05-26

本文共 7673 字,大约阅读时间需要 25 分钟。

晚上加班的时候,策划一直在耳边念叨数值的事儿。有些心烦意乱,顺口吐槽到,不如把数值运算丢给服务器人员去算。

哪知策划立马就说,这不行,他们原来服务器进行六十多位的运算时候,服务器炸了。

一说这个我就不乐意了,正好前端时间写了个超大数运算的方法,拿来检测下。

var _nu = "83497893246298346827346872346982360823579357623984623957438574309580293583209572309857846982364932784687236478921740172340912784901274879216478916298461298437612984316712984761298471298471284798124791284782146871324617892461928746981723647438926478321740912374809128740128409217844321462141912849021834274623784631728461782461728";        var _f = "543897489324789234723884709284201480924788903275498327";        Debug.Log(LargeNumberCalculator.BigDatenumMulitfy(_nu, _f));

运算结果如图所示:

45414294500570946232766941981487532736101951529219837603814751565682140750606060305830153788739377945894441114448047125337713342779005019904853971980122004902613506487483958423414305100219402340260863310057396394835279845410829944230707927439104713224781013599416389511098350559798301920310589352886075269035259304696264356729808295144044599752214530030747527087148415956028005529056

大致验算下,位数7*8=56是正确的。具体的数换个计算方式一样,说明应该是正确的。

再换个数计算:

var _nu = "83497893246298346827346872346982360823579357623984623957438574309580293583209572309857846982364932784687236478921740172340912784901274879216478916298461298437612984316712984761298471298471284798124791284782146871324617892461928746981723647438926478321740912374809128740128409217844321462141912849021834274623784631728461782461728";        var _f = "7000000000000000000";        Debug.Log(LargeNumberCalculator.BigDatenumMulitfy(_nu, _f));

结果为:

584485252724088427791428106428876525765055503367892367702070020167062055082467006169004928876554529492810655352452181206386389494308924154515352414089229089063290890216990893329089299089298993586873538993475028099272325247233501228872065532072485348252186386623663901180898864524910250234993389943152839922366492422099232477232096000000000000000000

首位运算大致没错,耗时不到几毫秒,起码不会蹦。

这个梗可真是:我曾在极度愤怒的情况下,完成几百位的乘法运算。

 

 

代码用的是之前写的天文级别运算方法,按位去计算。不过其实C#是提供有个BigInteger类来处理的。这里公开下关于BigInteger部分的源码:

using System.Collections;using System.Collections.Generic;using System.Numerics;using UnityEngine;/// /// 大数计算器/// public class LargeNumberCalculator{    ///     /// 大数比较    ///     public static bool BigDateCompare(string _st1, string _st2)    {        var _sA1 = _st1.Split('.');        var _sA2 = _st2.Split('.');        try        {            BigInteger _b1 = BigInteger.Parse(_sA1[0]);            BigInteger _b2 = BigInteger.Parse(_sA2[0]);            if (BigInteger.Compare(_b1, _b2) >= 0) return true;        }        catch        {        }        return false;    }    ///     /// 大数相加    ///      public static string BigDataPlus(string _st1, string _st2)    {        var _sA1 = _st1.Split('.');               var _sA2 = _st2.Split('.');        try        {            BigInteger _b1 = BigInteger.Parse(_sA1[0]);            BigInteger _b2 = BigInteger.Parse(_sA2[0]);            _b1 = BigInteger.Add(_b1, _b2);            var _num = 0f;            if (_sA1.Length > 1) _num += GetBigdateFloat(_sA1[1]);                         if (_sA2.Length > 1) _num += GetBigdateFloat(_sA2[1]);            _b1 = BigInteger.Add(_b1, (int)_num);            return GetFewBehind("" + _b1,_num);        }        catch        {        }        return _st1;    }    ///     /// 大数相减:只支持被减数大于减数    ///      public static string BigDataSUB(string _st1, string _st2)    {        var _sA1 = _st1.Split('.');        var _sA2 = _st2.Split('.');        try        {            BigInteger _b1 = BigInteger.Parse(_sA1[0]);            BigInteger _b2 = BigInteger.Parse(_sA2[0]);            if (BigInteger.Compare(_b1, _b2) < 0) return "0";            _b1 = BigInteger.Subtract(_b1, _b2);            var _num = 0f;            if (_sA1.Length > 1) _num += GetBigdateFloat(_sA1[1]);            if (_sA2.Length > 1)            {                //借一位相减                _b1 = BigInteger.Add(_b1, -1);                _num = _num + 1 - GetBigdateFloat(_sA2[1]);            }            _b1 = BigInteger.Add(_b1, (int)_num);            return GetFewBehind("" + _b1, _num);        }        catch        {        }        return _st1;    }    ///     /// 计算某位与一个数字相乘        ///     public static string BigDatenumMulitfy(string _s1, string _s2)    {        //Debug.Log("~~~~~~~~~~~~~"+_s1+"   "+_s2);        var _sA1 = _s1.Split('.');        var _sA2 = _s2.Split('.');        try        {            var _num = 1;            var _get1 = "" + _sA1[0];            var _get2 = "" + _sA2[0];                       if (_sA1.Length > 1)            {                _get1 +=  "" + GetBigdateIntToString(_sA1[1]);                //Debug.Log(_get1);                _num *= 1000;            }            if (_sA2.Length > 1)            {                _get2 += "" + GetBigdateIntToString(_sA2[1]);                //Debug.Log(_get2);                _num *= 1000;            }            BigInteger _b1 = BigInteger.Parse(_get1);            BigInteger _b2 = BigInteger.Parse(_get2);            //Debug.Log(_b1 + "   " + _b2);            _b1 = BigInteger.Multiply(_b1, _b2);            //Debug.Log(_b1 + "   " + _num);            BigInteger _remainder = 0;            _b1 = BigInteger.DivRem(_b1, _num, out _remainder);            //Debug.Log("..." + _b1);            //Debug.Log(BigDateRounding(GetStrForBigdate("" + _remainder, _num)) + "   " + GetStrForBigdate("" + _remainder, _num));            if (_remainder > 0) return _b1 + "." + BigDateRounding(GetStrForBigdate("" + _remainder, _num));            return ""+_b1;                                }        catch        {        }        return _s1;    }    ///     /// 大数与float相乘,得出一个大数    ///     public static string BigDatenumMulitfy(string _str1, float _f2)    {       return BigDatenumMulitfy(_str1, _f2.ToString());    }    ///     /// float与float相乘,得出一个大数    ///     public static string BigDatenumMulitfy(float _f1, float _f2)    {        return BigDatenumMulitfy(_f1.ToString(), _f2);    }    ///     /// 获得只包含前三位的float值    ///     private static float GetBigdateFloat(string _str)    {        var _arr = _str.ToCharArray();        var _zero = "0.";        for (var _i = 0; _i < 3; _i++)        {            if (_i < _arr.Length) _zero += _arr[_i];        }        return float.Parse(_zero);    }    private static string GetBigdateIntToString(string _str)    {        var _arr = _str.ToCharArray();        var _zero = "";        for (var _i = 0; _i < 3; _i++)        {            if (_i < _arr.Length) _zero += _arr[_i];            else _zero += "0";        }        return /*int.Parse*/(_zero);    }    private static string GetStrForBigdate(string _str,int _bit)    {        _bit = _bit.ToString().Length - 1;        var _cNum = _bit - _str.Length;        for (var _i = 0; _i < _cNum; _i++) _str = "0" + _str;        _str = _str.Substring(0, 3);        return BigDateRounding(_str);    }    ///     /// 后去零    ///     private static string BigDateRounding(string _str)    {        for (var _i = _str.Length - 1; _i >= 0; _i--)        {            if (_str[_i] == '0')            {                _str = _str.Substring(0, _str.Length - 1);            }             else return _str;        }        return _str;    }    ///     /// 补全小数点后几位    ///     /// 
private static string GetFewBehind(string _str, float _f) { var _arr = _f.ToString().Split('.'); if (_arr.Length > 1) { _str += "."; var _theArr = _arr[1].ToCharArray(); for (var _i = 0; _i < 3; _i++) { if (_i < _theArr.Length) _str += _theArr[_i]; } return _str; } else { return _str; } }}

这个思路也是拼接运算,其实放到java或者其他语言里面去,计算原理也是一样。

有需要的朋友,自己拿去。

转载地址:http://iowli.baihongyu.com/

你可能感兴趣的文章
5000起步没商量!vivo NEX 3S 5G手机正式发布:骁龙865+无界瀑布屏加持
查看>>
二月1500-1999元性价比排行榜:前三都是魅族手机
查看>>
疫情下的“双11”,品牌逆势增长背后的数字化变革
查看>>
支付宝变色了!被绑架了你就眨眨眼?官方如此回应...
查看>>
罗永浩欲直播带货,京东说可以帮忙联系
查看>>
B站,正在变成下一个“公众号”?
查看>>
小米启动安心服务月 手机家电产品可免费清洁保养
查看>>
刘作虎:一加新品将全系支持 5G
查看>>
滴滴顺风车上线新功能,特殊时期便捷出行
查看>>
不会延期!iPhone 12S预计如期在9月发售:升级三星LTPO屏幕
查看>>
NFS共享服务
查看>>
LINUX系统安全及应用
查看>>
LINUX进程和计划任务管理
查看>>
iptables 防火墙
查看>>
Firewalld 防火墙
查看>>
rsync下行同步和inotify实时同步部署
查看>>
docker-harbor私有仓库
查看>>
ansible自动化运维
查看>>
ansible-playbook
查看>>
ansible templates+roles
查看>>