九的余数

本文介绍了一个快速计算任意自然数除以9后的余数的方法,并通过数学证明了该方法的有效性。该算法适用于位数不超过一百万的大整数,通过对每个数字进行加总再取模的方式简化计算过程。

现在给你一个自然数n,它的位数小于等于一百万,现在你要做的就是求出这个数整除九之后的余数。

输入
第一行有一个整数m(1<=m<=8),表示有m组测试数据;
随后m行每行有一个自然数n。
输出
输出n整除九之后的余数,每次输出占一行。

#include<iostream>
#include<string>
using namespace std;


int a[1000000];


int main()
{
int m;
string str;
cin >> m;
int len;
while (m--)
{
int sum = 0;
cin >> str;
len = str.length();
for (int i = 0; i < len; i++)
{
sum += (str[i] - '0');
}
cout << sum % 9 << endl;
}
return 0;
}





怎样证明:一个数除以9的余数等于它的数字和除以九的余数?

首先10^i =99...9(i个9) +1除以9的余数=1
所以ai*10^i除以9的余数=ai
用a0~an表示各位数字则

数=(anan-1an-2..........a2a1a0),
 =an*10^n+an-1*10^n-1 +an-2 *10^n-2 +...........a2*10^2+a1*10+a0
除以9的余数=an +an-1 +an-2 +..............+a2 +a1 +a0

### 余数补码修正 详细解析 --- ## 一、什么是余数补码修正? 在**大整除法**中,我们常将一个超大拆分成多个固定大小的块(如32位一块),逐块进行除法。在这个过程中,每一块除法都会产生一个**余数**,这个余数会传递给下一块继续参与运算。 但在某些情况下,余数可能会是**负**(如使用近似估算时),这时我们需要进行**补码修正**,将其转换为等效的**无符号表示**,以便后续计算。 --- ## 二、为什么需要补码修正? ### 1. C语言中无符号与有符号的区别 在C语言中: - 有符号整(如 `int32_t`)用**补码形式**表示负; - 无符号整(如 `uint32_t`)总是用**正整**表示,范围为 `0 ~ 2^32 - 1`。 当你将一个负赋给无符号类型时,它会自动转换为补码对应的无符号值。 ### 例如: ```c int32_t r = -1234; uint32_t ur = (uint32_t)r; // ur = 4294966062 ``` 这一步本质上就是**补码转换**。 --- ## 三、函中的补码修正语句 ```c u4_wari += (((U4)KSPD_U4UNDER + u4_mod) / ((U4)u2_spdpls)); ``` 其中: - `u4_mod`:是一个**累积的余数**(可能是负); - `KSPD_U4UNDER`:是常量 `0xFFFFFFFF`(即 $ 2^{32} - 1 $); - `u2_spdpls`:是除。 --- ## 四、学含义解析 我们先看表达式: $$ \text{修正值} = \frac{KSPD\_U4UNDER + u4\_mod}{u2\_spdpls} = \frac{2^{32} - 1 + r}{d} $$ 其中: - $ r $ 是当前余数(可能为负); - $ d $ 是除。 ### 情况一:$ r \geq 0 $ 如果余数是非负: $$ \text{修正值} = \left\lfloor \frac{2^{32} - 1 + r}{d} \right\rfloor $$ 此时这个值是正常的除法结果,不会改变原有逻辑。 ### 情况二:$ r < 0 $ 如果余数是负: $$ \text{修正值} = \left\lfloor \frac{2^{32} - 1 + r}{d} \right\rfloor = \left\lfloor \frac{r + 2^{32} - 1}{d} \right\rfloor $$ 这个值等价于将负余数 $ r $ 转换为**无符号等效值**,再除以除。 这正是我们想要的“补码修正”。 --- ## 五、为什么这样能修正余数? 我们知道,在32位无符号整中: $$ r_{\text{signed}} = -x \quad \Rightarrow \quad r_{\text{unsigned}} = 2^{32} - x $$ 所以: $$ r_{\text{unsigned}} = r_{\text{signed}} + 2^{32} $$ 而在函中: $$ KSPD\_U4UNDER + r_{\text{signed}} = 2^{32} - 1 + r_{\text{signed}} = r_{\text{unsigned}} - 1 $$ 因此: $$ \text{修正商} = \left\lfloor \frac{r_{\text{unsigned}} - 1}{d} \right\rfloor $$ 这可以理解为对余数部分的一次“调整除法”。 --- ## 六、举例说明 ### 假设: - `u4_mod = -1234` - `KSPD_U4UNDER = 0xFFFFFFFF = 4294967295` - `u2_spdpls = 83` 则: $$ \text{修正商} = \left\lfloor \frac{4294967295 - 1234}{83} \right\rfloor = \left\lfloor \frac{4294966061}{83} \right\rfloor = 51746555 $$ 最终: ```c u4_wari += 51746555; ``` 这就是一次典型的**余数补码修正操作**。 --- ## 七、作用总结 | 补码修正的作用 | 说明 | |----------------|------| | 1. 负余数处理 | 将负余数转换为等效无符号值 | | 2. 防止溢出 | 避免负值影响后续运算 | | 3. 商值调整 | 修正由于近似除法导致的误差 | | 4. 精度提高 | 提高最终商值的准确性 | | 5. 兼容无符号运算 | 与后续无符号计算逻辑一致 | --- ## 八、图示说明 ```text 余数 r = -1234 ↓ 补码转换 = 0xFFFFFFFF + (-1234) = 4294966061 ↓ 除以除 d = 83 → 修正商 = 51746555 ↓ 加到最终商 u4_wari 中 ``` --- ## 、应用背景 这种补码修正方法广泛应用于: - **嵌入式系统中的大除法** - **无硬件除法器的底层驱动** - **编译器模拟除法运算** - **高精度值库(如 Java BigInteger)** - **密码学算法中的模运算** --- ## 十、总结一句话 > **余数补码修正是将负余数转换为无符号等效值,并参与除法修正的一种学技巧,用于提高大除法精度运算稳定性。** 如你有任何关于该函进一步扩展、优化或封装为通用函的需,我也可以继续为你提供帮助。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值