精华内容
下载资源
问答
  • 2019-04-16 19:32:15

    先看一个例子,将两个32位的Int型数相乘,将结果赋给long型变量。

    long a=111111 * 111111;  
    

    乍一看好像没毛病,但这是个坑,慎跳!相乘以后的值会溢出。

    原因:
    对于编译器来说,int和int相乘,结果也是先存在int中,跟被赋给long还是longlong数据类型的字段没有关系。

    解决办法:
    想要不溢出,就要把两个32位数强制转换成long类型,再相乘。

    更多相关内容
  • 【题意】找到由个n位数相乘得到的最大回文。由于返回的结果可能会很大,所以结果为乘积 % 1337。n的范围是[1,8]。https://leetcode.com/problems/largest-palindrome-product/discuss/96306 解决这个问题有个...

    问题:

    Find the largest palindrome made from the product of two n-digit numbers.

    Since the result could be very large, you should return the largest palindrome mod 1337.

    Example:

    Input: 2

    Output: 987

    Explanation: 99 x 91 = 9009, 9009 % 1337 = 987

    Note:

    The range of n is [1,8].

    解决:

    【题意】找到由两个n位数相乘得到的最大回文。由于返回的结果可能会很大,所以结果为乘积 % 1337。n的范围是[1,8]。https://leetcode.com/problems/largest-palindrome-product/discuss/96306

    解决这个问题有两个方向:一是先构造回文,然后判断它是否可以写成两个n位数的乘积; 另一种是首先获得两位数字的乘积,然后判断乘积是否是回文

    ① 先构造回文,然后判断它是否可以写成两个n位数的乘积:

    首先,需要考虑两个问题:

    1. 如何构建回文并按降序排列(我们只需要最大回文数)。

    2. 如何判断一个给定的回文数可以写成两个数的乘积。

    对于第一个问题,我们需要知道每个回文中有多少位数。由于回文是两个n位数的乘积,所以它可以有2n或2n - 1位数。而且,由于我们只需要最大回文数,因此我们将首先考虑2n位的回文。这些回文可以分为数字相同的两部分(每部分n个):左和右。左边是右边的镜像,反之亦然。 因此,每个回文将完全由其左边或右边的部分决定。

    需要注意的是,左边的部分是一个n位的数字,如果我们按照降序排列,最终的回文也会按降序排列。因此,我们可以从最大的n位数向最小的n位数遍历。对于每个数字,我们可以通过连接数字和镜像来构建回文。

    对于第二个问题,即如何判断一个给定的回文数可以写成两个数的乘积。这本质上是“整数分解”问题。一种简单的方法是“尝试分割”算法,即测试每个n位数以查看它是否是回文数的因子,如果是,则另一个因子也是n位数字。

    注意我们只考虑了2n位的回文。 幸运的是,对于每种情况(n = 1到8),我们能够找到至少一个可以分解成两个n位数字的回文,因此不需要检查那些具有2n - 1个数字的回文。O(10^n)

    class Solution { //387ms
        public int largestPalindrome(int n) {
            if (n == 1) return 9;
            long max = (long) Math.pow(10,n) - 1;//n位数的最大回文,上界
            long min = max / 10;//下界
            for (long p = max;p > min;p --){//从大到小,构造回文
                long left = p;//最大回文的左半部分
                long right = 0;
                for (long i = p;i != 0;i /= 10){
                    right = right * 10 + i % 10;
                    left *= 10;
                }
                long palindrome = left + right;//构造回文序列
                for (long i = max;i > min;i --){
                    long j = palindrome / i;
                    if (j > i || j <= min) break;//如果另一个因子大于当前因子,或者不是n位数,则终止
                    if (palindrome % i == 0) return (int)(palindrome % 1337);//如果当前数是一个因子,则找到了满足条件的最大回文
                }
            }
            return 9;//n = 1时
        }
    }

    ② 根据上面的分析,我们只需要关注最大回文数即可,所以可以从9开始检查回文。如果没找到,则从8,7,6,...开始检查。如果这个回文数是以9开始的,则其结尾也应该是9。如果回文数是两个n位数的乘积,则这两个数应该以1,3,7,9结尾。对于其他的情况也是如此。

    对于每个n来说,至少存在一个具有2n位的回文数,它以数字9开始,可以写成两个n位数的乘积。

    经过分析,有如下结论:对于每个n,存在至少两个n位数字num1和num2,10 ^ n-10 ^ m <= num1,num2 <= 10 ^ n -1和m = [ n + 1)/ 2],其乘积将是回文数

    先得到两个n位数的乘积,再判断乘积是否是回文。

    与第一种方法类似,我们需要考虑以下两个问题:

    1. 如何构建乘积并降序排列。

    2. 如何判断给定的乘积是回文数。

    第二个问题很简单,只需将乘积倒过来,并判断它是否与原来的乘积相同。 但是,第一个问题有点困难。 获得乘积是一件容易的事。 困难的部分是如何按降序排列。

    首先我们需要确定候选乘积。 从上面的分析看,我们只考虑在[10 ^ n - 10 ^ m,10 ^ n - 1]范围内两个n位数字获得的乘积。其次,我们可以使用PriorityQueue以降序提取这些候选乘积。

    然而,当n = 8时,上面候选乘积的总数仍然很多。所以我们需要进一步的修剪:

    首先,由于乘积以数字9结尾,所以两个数字必须以数字1,3,7或9结尾。
    其次,为了避免重复,第一个数字不会小于第二个。
    第三,对于第一个因子固定的所有乘积,没有必要一次把所有乘积都记下来,而是可以考虑将第二个因子按顺序递减来遍历。
    最后我们将这两个因子存储在PriorityQueue中,同时根据他们的乘积提取它们。

    class Solution {//275ms
        public int largestPalindrome(int n) {
            //两个因子的范围[10^n - 10^m, 10^n - 1],m = [(n+1)/2]
            int max = (int) Math.pow(10,n) - 1;
            int min = max - (int) Math.pow(10,(n + 1) >> 1);
            Comparator<int[]> cmp = new Comparator<int[]>() {
                @Override
                public int compare(int[] o1, int[] o2) {//将乘积按降序排列
                    return Long.compare((long) o2[0] * o2[1],(long) o1[0] * o1[1]);
                }
            };
            PriorityQueue<int[]> priorityQueue = new PriorityQueue<>(max - min,cmp);
            for (int i = max;i > min;i --){
                int tail = i % 10;
                if (tail == 3 || tail == 7){
                    priorityQueue.offer(new int[]{i,i});
                }else if (tail == 1){
                    priorityQueue.offer(new int[]{i,i - 2});
                }else if (tail == 9){
                    priorityQueue.offer(new int[]{i,i - 8});
                }
            }
            while (! priorityQueue.isEmpty()){
                int[] tmp = priorityQueue.poll();
                long palindrome = (long) tmp[0] * tmp[1];
                if (isPalindrome(palindrome)){
                    return (int)(palindrome % 1337);
                }
                if (tmp[1] > min){
                    tmp[1] -= 10;
                    priorityQueue.offer(tmp);
                }
            }
            return 0;
        }
        public boolean isPalindrome(long x){
            long reverse = 0;
            for (long tmp = x; tmp != 0;tmp /= 10){
                reverse = reverse * 10 + tmp % 10;
            }
            return reverse == x;
        }
    }

    转载于:https://my.oschina.net/liyurong/blog/1603314

    展开全文
  • asm 2个32位数相乘=一个64位数

    千次阅读 2016-08-07 22:06:32
    This is two dword number make multiplication , and finally get a qword number中文解释:就是输入个32位(十进制)有符号(-2147483648~2147483647)[经计算器检验结果完全正确] "输出表达式"在 CMD 下,我...
    TITLE multiplication
    comment !
    
    This is two dword number make multiplication , and finally get a qword number
    
    中文解释:就是输入两个32位(十进制)有符号数(-21474836482147483647)[经计算器检验结果完全正确]
         "输出表达式"在 CMD 下,我均采用了十六进制,
         例:2147483647(十进制)*2147483647(十进制)=3FFFFFFF00000001(十六进制)
             2147483647(十进制)*(-2147483647)(十进制)=c00000008000000(十六进制)
    
    解题思路:①先将输入的两个有符号数的最高位取出进行(异或)判断,确定结果符号。
             ②将输入的有符号数进行处理(neg)处理,全转化为正数(归一法)
             ③将乘数右移移位,取出当前最低位,(然后你懂的),循环到乘数等于0
             ④若相乘后的结果还是32位数,就输出十进制数
             ⑤若先前的出的结果符号为负,就将64位数(减1取not)
    
    !
    include irvine32.inc
    
    .data
    value1 dword 0
    temp1 dword 0       ;正数
    value2 dword 0
    temp2 dword 0       ;正数
    result qword 0
    resultTemp qword 0
    sign0 byte 0        ;0表示正数,1表示负数(存放结果符号)
    sign1 byte 0
    strTitle byte "TITLE:两32位(有符号)二进制数相乘得到一个64位二进制数",0
    str1 byte "请输入被乘数(带符号十进制):",0
    str2 byte "请输入乘数(带符号十进制):",0
    str3 byte "结果为:(十六进制,括号内为十进制数)",0
    
    .code
    ;==============
    getValue proc;读入两有符号数(若输入溢出会提示)
    mov edx,offset strTitle
    call writestring
    call crlf
    mov edx,offset str1
    call writestring
    call crlf
    call readint
    mov value1,eax
    mov temp1,eax
    mov edx,offset str2
    call writestring
    call crlf
    call readint
    mov value2,eax
    mov temp2,eax
    ret
    getValue endp
    ;==============
    getSign proc;先计算两数相乘后结果的符号(将两有符号数相乘化简为无符号数相乘)
    mov eax,value1
    shl eax,1
    jnc NEXT1_1
    mov al,1
    mov sign0,al
    neg temp1
    NEXT1_1:
    mov eax,value2
    shl eax,1
    jnc NEXT1_2
    mov al,1
    mov sign1,al
    neg temp2
    NEXT1_2:
    mov al,sign1
    xor sign0,al
    mov eax,0
    movzx eax,sign0
    ret
    getSign endp
    ;==============
    calculate proc;计算两无符号数相乘的结果
    mov eax,temp1
    mov dword ptr resultTemp,eax
    shr temp2,1
    jnc BEGIN
    mov edx,dword ptr resultTemp+4
    mov eax,dword ptr resultTemp
    add dword ptr result,eax
    adc dword ptr result+4,edx
    BEGIN:
    ;每次都要移动保存被乘数移位后的值
    cmp temp2,0
    jz OK
    mov eax,dword ptr resultTemp+4
    shl dword ptr resultTemp,1
    jnc NEXT2_1
    shl eax,1
    inc eax
    mov dword ptr resultTemp+4,eax
    jmp NEXT2_3
    NEXT2_1:
    shl eax,1
    mov dword ptr resultTemp+4,eax
    NEXT2_3:
    ;进行比较乘数的二进制最低位是否为
    shr temp2,1
    jnc BEGIN
    mov eax,dword ptr resultTemp
    mov edx,dword ptr resultTemp+4
    add dword ptr result,eax
    adc dword ptr result+4,edx
    jmp BEGIN
    OK:
    ret
    calculate endp
    ;==============
    makeResult proc;根据符号求最终结果
    cmp sign0,0
    jz NEXT3_1
    mov eax,dword ptr result
    mov edx,dword ptr result+4
    cmp eax,0        ;若低位为0则要减高位(结果等0的情况已被讨论过)
    jnz NEXT3_2
    dec edx
    NEXT3_2:
    dec eax
    not eax
    not edx
    mov dword ptr result,eax
    mov dword ptr result+4,edx
    NEXT3_1:
    ret
    makeResult endp
    ;==============
    output proc;输出最终结果(小于32位的直接用十进制输出,方便检验)
    mov edx,offset str3
    call writestring
    call crlf
    mov eax,value1
    call writeHex
    mov al,"*"
    call writechar
    
    mov eax,value2
    call writeHex
    mov al,"="
    call writechar
    
    mov eax,dword ptr result+4
    call writeHex
    mov edx,eax
    mov eax,dword ptr result
    call writeHex
    
    cmp edx,0                ;小于32位的正数(edx存的是结果的高位)
    jnz NEXT4_1
    mov al,'('
    call writechar
    mov al,'+'
    call writechar
    mov eax,dword ptr result
    call writedec
    mov al,')'
    call writechar
    
    NEXT4_1:
    cmp sign0,0                 ;小于32位正数也讨论过
    jz NEXT4_2                  ;将小于32位负数化为十进制
    mov eax,dword ptr result+4
    mov edx,dword ptr result
    cmp edx,0
    jnz NEXT4_3
    dec eax
    NEXT4_3:
    dec edx
    not edx
    not eax
    cmp eax,0
    jnz NEXT4_2
    shl edx,1
    jc NEXT4_2
    shr edx,1
    mov al,'('
    call writechar
    mov al,'-'
    call writechar
    mov eax,edx
    call writedec
    mov al,')'
    call writechar
    NEXT4_2:
    call crlf
    call readchar
    ret
    output endp
    ;==============
    main proc
    call getValue
    ;若两数有一个是0则结果也是0
    cmp temp1,0
    jz NEXT3_1
    cmp temp2,0
    jz NEXT3_1
    ;============
    call getSign
    call calculate
    call makeResult
    NEXT3_1:
    call output
    exit
    main endp
    end main
    展开全文
  • 第一步:乘数的最后一位相乘,题中则是6*7==42,乘积最后一位是6,是因为它不是十进制乘法,所以42%n==6,得出这个结果就把B选项排除。但是选项中的9、12、18都可以使42%n==6,所以进行下一步; 第二步:...

    以例题为例:假设在n进制下,下面的等式成立567*456=150216,则n 的值是(D)

                A:9  B:10  C:12  D:18

    求解步骤:

    第一步:两乘数的最后一位相乘,题中则是6*7==42,乘积最后一位是6,是因为它不是十进制乘法,所以42%n==6,得出这个结果就把B选项排除。但是选项中的9、12、18都可以使42%n==6,所以进行下一步;

    第二步:任何一个数字都可以这样表示   例:1234=1*n^3+2*n^2+3*n^1+4

     同理:567*456=150216可以写成:

    (5*n^2+6*n^1+7)*(4*n^2+5*n^1+6)  =  1*n^5+5*n^4+2*n^2+1*n^1+6

    合并同类项得:20*n^4+49*n^3+88*n^2+71*n+41  =  n^5+5*n^4+2*n^2+n+6

    两边同时取余得:42%n==6;(验证了第一步)

    第三步:由于还是无法确定具体答案,所以继续对两边同时除以n,再同时队其取余

    得:(71+41/n)% n=(1+6/n)==1

    再分别把A、C、D选项带进去验算,只有D:18符合题意,故正确答案是D。

    展开全文
  • 大数相乘:假设有A和B个大数,位数分别为a和b。根据我们平常手动计算乘法的方式可以看出,最终的结果的位数c一定小于等于a+b,我们可以举一个简单的例子来说明,99*999=98901,最终结果是五位(a+b)。下面我们根据...
  • 它表示:数相乘等于一个乘以一个三位。 如果没有限定条件,这样的例子很多。 但目前的限定是:这9个方块,表示1~9的9个数字,不包含0。 该算式中1至9的每个数字出现且只出现一次! 比如: 46...
  • 由于个3位数相乘最大结果即999*999 = 998001,因此可以设置6个变量分别表示六个位数上的数值,并在合适的计算下将该颠倒,即类似于将123456颠倒为654321,再与原进行对比。如果是回文,例如123321,则颠倒后与...
  • 所以,以个字符窜的长度和构建一个int[]型数组,个数字相乘其结果最多为个数字的总长度和 int[] temp = new int[num1.length() + num2.length()]; 再以个for循环将其存放至我们构建的数组内,注意遍历...
  • 个三位数相乘得到的最大回文 所谓的回文是指: 一个像14641这样“对称”的,即:将这个的数字按相反的顺序重新排列后,所得到的和原来的一样。这里,“回文”是指像“妈妈爱我,我爱妈妈”这样的,...
  • 之前分享过个实数相减的...今天要贴的代码是个实数相乘问题,由于具体算法步骤题目已经给出,所以按步骤编写就出来了。编译环境是DEVC++如有问题或发现错误 欢迎指出~~/*题目3个实数相乘!!!例如:输入strin...
  • 问题大整数相乘思路说明对于大整数计算,一般都要用某种方法转化,否则会溢出。但是python无此担忧了。Python支持“无限精度”的整数,一般情况下不用考虑整数溢出的问题,而且Python Int类型与任意精度的Long整数类...
  • 带符号多数位数相乘

    千次阅读 2019-01-11 19:23:25
    带有符号的多位数相乘 以199×29为例 基本时执行步骤如下图 完整代码 #include &amp;lt;stdio.h&amp;gt; #include &amp;lt;string.h&amp;gt; #include&amp;lt;stdlib.h&amp;gt; #define ...
  • 像简单的两数相乘我们可以大致推断出答案。10进制下个位相乘即54=20而题目中个位为2,我们拿选项检验20对谁取余能得到2。很显然答案就是6了。20%2=2。 但是像这种题:假设在n进制下,下面等式成立:567*456=150216...
  • 求由个三位数相乘得到的最大回文 什么是回文 回文是指一个,它从前往后读和从后往前读的结果是一样的。 比如9009,102343201 代码如下 #include<iostream> using namespace std; //判断一个是不是...
  • c语言实现个大数相乘

    千次阅读 2021-01-07 17:15:10
    实现个不限位十进制整数的乘法函数, demon #include<stdio.h> #include<string.h> int main() { int i,j,z,k; int f_m1,f_m2,f_k; int carry; int result_int_len; int x_len,y_len; int x...
  • i = int(input('请输入一个正整数:')) a = str(i) b = int(len(a)) #位数 for i in range(b): print(int(a[i])) print('位数为:%d位' % b)
  • python实现大数相乘

    千次阅读 2020-11-24 06:40:58
    一致2、创建存储结果数组,长度默认为个被乘数长度之和3、按位相乘并存储在对应的结果数组中5、执行进位操作,结果数组从0开始,如果大于9则进位到下一位并获取新结果6、结果执行逆序def multipy(aaa,bbb):aaa....
  • 如何用c语言计算小数点后位数

    千次阅读 2021-05-21 07:53:27
    这个要看小数按什么格式输入。如果按%s输入,也就是按字符串格式输入,先找到小数点的位置...}这是最后一个已经出现错误,所以遇到要精确判断小数点的位数,最好直接按字符串读入,这和图灵机的工作原理暗暗相合。 全部
  • 定义:吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序,以个0结尾的数字是不允许的。如1260 = 21 * 60,2187 = 27...
  • 我们平时接触的长乘法,按位相乘,是一种时间复杂度为 O(n ^ 2) 的算法。今天,我们来介绍一种时间复杂度为 O (n ^ log 3) 的大整数乘法(log 表示以 2 为底的对数)。介绍原理karatsuba 算法要求乘数与被乘数要满足...
  • 用java数组展示计算机的多位数相乘

    千次阅读 2020-10-12 22:50:04
    我们通常用java语言实现多位数相乘时,都是直接输入然后便会输出结果 例如:System.out.print(1234*567); 便直接得到结果: 699678 那计算机里面是怎么实现多位数相乘的呢? 换句话说,计算机不可能储存每个...
  • 整数相乘算法

    千次阅读 2020-03-28 11:44:08
    个整数相乘的算法 算法分析 24 * 13 第一步计算4 * 13: 4 * 3 = 12(3在个位,不需要补零) 4 * 1 = 4(1在十位,需要补1个零) 4在个位,则结果不需要补零 结果:12 + 4 * 10 = 52 第二步计算2 * 13: 2 * 3 =...
  • 浮点数精确运算的分析和解决办法1。01+2。01=3。022。01*2。...还有某位姓林的先生在某本书里提过=0的判断。嗯,如果你不遇到此问题,那你完全可以把它抛到火星上去,可惜,偶不好彩,这样的问题...
  • 位数的回文有多少个

    千次阅读 2021-05-20 02:04:49
    简介折叠编辑本段回文是指一个像16461这样“对称”的,即:将这个的数字按相反的顺序重新排列后,所得到的和原来的一样。这里,“回文”是指像“妈妈爱我,我爱妈妈”这样的,正读反读都相同的单词或句子...
  • 我们不妨直接从问题本身考虑,先算出位数相同的数相乘的最大积,将最大积分成左右半,根据左半边来构造回文。将回文构造出来之后,对乘数从大到小进行遍历。如果回文刚好能整除乘数,则说明这就是我们要...
  • 用java数组展示计算机的多位数相乘我们通常用java语言实现多位数相乘时,都是直接输入然后便会输出结果例如:System.out.print(1234*567);便直接得到结果: 699678那计算机里面是怎么实现多位数相乘的呢?...
  • 前几天在网上看到这样一个题目 “数相乘,小数点后的位数没有限制,写一个高效算法“,在网上搜集到一些想法,感觉”先做大数乘法,然后再给结果加小数点“这种方法更好一些,用c语言实现了,分享给大家。...
  • 判断最大回文乘积

    2022-03-21 22:01:55
    回文判断
  • 位整数相乘形成的最大回文是 9009 = 99 × 91。编写程序,求得任意输入的 n 位整数相乘形成的最大回文。 输入格式: 正整数 n 输出格式: n 位整数相乘形成的最大回文 输入样例: 2 输出样例: 9009 【基本...
  • 在C语言中,int 与 unsigned 乘法被...下面这段代码用来判断整数乘法会不会溢出:/*练习题2.36*//*开发环境VC++ 6.0*/#includevoid main(){unsigned x = 4294967295;unsigned y = 8;unsigned mul = x * y;int a = 2...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,954
精华内容 5,181
关键字:

判断两数相乘的位数