2的1024次方

目录

一、累积法

(1)“累乘积”算法模型

(2)代码实现

(3)结果分析

(4)二进制角度分析

二、位移法

(1)“位移”算法模型

(2)代码实现

(3)结果分析

三、long double 类型

(1)long double 类型

(2)代码实现

(3)优缺点分析

<优点>

<缺点>

四、字符数组模拟大整数乘法

(1)理论分析

(2)代码实现

(3)扩展


编程计算2的1024次方          

                        ——2023年迅雷面试题

一、累积法

(1)“累乘积”算法模型

①定义一个变量并赋初值为 1

②为每一个数据项提供一个通式

③循环遍历每一个数据项,并用初值为 1的变量累乘(*=)每一个数据项

④循环结束后,初值为 1的变量的值就是累乘的结果

(2)代码实现

#include<stdio.h>

int main(int argc,char** argv)
{
    int sum = 1;
    for(int i=0;i<1024;i++)
    {
        sum*=2;
    }
    printf("2^1024=%d\n",sum);
    return 0;
}

(3)结果分析

(4)二进制角度分析

①在二进制中,int 类型的值是一个 32 位的二进制数。

②当 result 不断乘以 2 时,它的二进制表示会不断左移。

③最终,所有有效位都被移出,剩下的都是 0,因此 result 变为 0。

二、位移法

(1)“位移”算法模型

位运算符<<(按位左移) 左移n位,数据乘以2的n次方

a=60    a<<2  a=240                            

32 << 2  = 32 * 2^2  = 128

16 << 4 = 16 * 2^4  =  256  

7 << 2 = 7 * 2^2 = 28

(2)代码实现

#include<stdio.h>
int main(int argc,char* argv)
{
    int sum = 1;
    sum <<=1024;
    printf("%d\n",sum);
    return 0;
}

(3)结果分析

warning: left shift count >= width of type [-Wshift-count-overflow]      
    sum = sum << 1024;

①程序最终输出的结果是 1,很可能是编译器在处理这个未定义行为时,把位移量进行了取模操作。

②也就是将 1024 对 int 类型的位数 32 取模,即 1024 % 32 = 0。

③这样一来,sum << 1024 实际上就相当于 sum << 0,而任何数左移 0 位都还是其本身,所以 sum 的值依旧是 1。

三、long double 类型

(1)long double 类型

①%Lf 表示要输出一个 long double 类型的变量

②%lf 表示要输出一个 double 类型的变量

③.0 表示不输出小数部分

(2)代码实现

#include<stdio.h>

int main(int argc,char* argv)
{
    long double sum=1;
    for(int i=0;i<1024;i++)
    {
        sum*=2;
    }
    printf("%.0lf\n",sum);
    return 0;
}

(3)优缺点分析

<优点>

①实现简单:代码逻辑直观,无需复杂数据结构与算法,便于理解,可快速实现计算

②可处理大数:相比 float 和 double,long double 精度更高、范围更大,一定程度上能应对 2 的 1024 次方计算

<缺点>

①精度损失:浮点数以二进制存储运算,对 2 的 1024 次方这类大数无法精确表示每一位,可能存在“四舍五入”情况

②可能溢出:2 的 1024 次方极大,在不同的编译环境中可能超出 long double 表示范围,造成溢出

③不适精确计算:在对精度要求高的场景中不适用,需要考虑其他方式

四、字符数组模拟大整数乘法

(1)理论分析

(2)代码实现

#include <stdio.h>
#include <string.h>

// 反转字符串函数
void reverse(char* result_str) 
{
    // 计算字符串的长度
    int length = strlen(result_str);
    // 遍历字符串的前半部分
    for (int i = 0; i < length / 2; i++) 
    {
        // 交换当前位置和对称位置的字符
        char temp = result_str[i];
        result_str[i] = result_str[length - 1 - i];
        result_str[length - 1 - i] = temp;
    }
}

// 计算 2 的 n 次方
void calculate_t(int idex, char *result_str, int result_size) 
{
    int carry = 0;  // 进位标志
    int result_length = 1; 

    // 循环 idex 次
    for (int i = 0; i < idex; i++) 
    {
        carry = 0;  
        for (int j = 0; j < result_length; j++) 
        {
            // 将字符转换为对应的数字
            int digit = result_str[j] - '0';
            
            // 乘以 2 并加上进位
            digit = (digit * 2) + carry;
            
            // 计算新的进位
            carry = digit / 10;
            
            // 将结果的个位转换为字符存回字符串
            result_str[j] = digit % 10 + '0';
        }
        
        // 处理最后的进位
        while (carry > 0) 
        {
            // 检查数组是否还有空间存储新的数字
            if (result_length >= result_size - 1) 
            {
                printf("数组空间不足,无法存储完整结果!\n");
                return;
            }
            // 将进位的个位转换为字符存入结果字符串
            result_str[result_length++] = carry % 10 + '0';
            // 进位除以 10,处理更高位的进位
            carry /= 10;
        }
    }
    
    // 添加字符串结束符
    result_str[result_length] = '\0';
    
    reverse(result_str);
}

int main() 
{
    int idex = 1024;  
    char result[2048] = {'1'};
    int result_size = sizeof(result);
    
    calculate_t(idex, result, result_size);
    
    printf("2 的 %d 次方的结果是:\n%s\n", idex, result);
    return 0;
}    

(3)扩展

引入“位移”算法模型:

位运算符<<(按位左移)

结果存放在字符数组中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值