我需要使用uint64_t
asunsigned long long int
因为我需要适应比unsigned long
它更大的数字?(两个操作系统都是 64 位),我该如何解决这个问题?这是实现二进制除法的代码: 这是我尝试打印以查看最终函数结果的函数:
void binary_div(s21_big_decimal *value_1, s21_big_decimal value_2, s21_big_decimal *result) {
init_s21_decimal(result);
s21_big_decimal Q;
s21_big_decimal R;
int scaleDiv = -1;
do {
init_s21_decimal(&R);
init_s21_decimal(&Q);
scaleDiv++;
int lastBit = (SIZE_BIG_DECIMAL - 1) * 32 - 1;
int currentBit = get_bit_big(*value_1, lastBit);
while (currentBit == 0 && lastBit >= 0) {
currentBit = get_bit_big(*value_1, lastBit);
if (currentBit == 0) lastBit--;
}
for (int i = lastBit; i >= 0; i--) {
change_left_big(&R, 1);
set_bit_big(&R, 0, get_bit_big(*value_1, i));
if (is_less_or_equal_big(value_2, R)) {
s21_big_decimal res = {0};
init_s21_decimal(&res);
s21_sub_big(R, value_2, &res);
init_s21_decimal(&R);
copy_bits(res, &R);
set_bit_big(&Q, i, 1);
}
}
if (scaleDiv > 0) {
mul_10_big(result);
}
s21_big_decimal res;
init_s21_decimal(&res);
add_big(*result, Q, &res);
copy_bits(res, result);
if (!is_zero_big(R)) {
init_s21_decimal(value_1);
mul_10_big(&R);
copy_bits(R, value_1);
}
} while (!is_zero_big(R) && scaleDiv < 28);
set_scale_big(result, scaleDiv);
for (int i = 0; i < 7; i++) {
printf("%lX ", result->bits[i]);
}
printf("\n");
}
Run Code Online (Sandbox Code Playgroud)
我使用位,这里是函数 mul_10_big 的示例:
void binary_div(s21_big_decimal *value_1, s21_big_decimal value_2, s21_big_decimal *result) {
init_s21_decimal(result);
s21_big_decimal Q;
s21_big_decimal R;
int scaleDiv = -1;
do {
init_s21_decimal(&R);
init_s21_decimal(&Q);
scaleDiv++;
int lastBit = (SIZE_BIG_DECIMAL - 1) * 32 - 1;
int currentBit = get_bit_big(*value_1, lastBit);
while (currentBit == 0 && lastBit >= 0) {
currentBit = get_bit_big(*value_1, lastBit);
if (currentBit == 0) lastBit--;
}
for (int i = lastBit; i >= 0; i--) {
change_left_big(&R, 1);
set_bit_big(&R, 0, get_bit_big(*value_1, i));
if (is_less_or_equal_big(value_2, R)) {
s21_big_decimal res = {0};
init_s21_decimal(&res);
s21_sub_big(R, value_2, &res);
init_s21_decimal(&R);
copy_bits(res, &R);
set_bit_big(&Q, i, 1);
}
}
if (scaleDiv > 0) {
mul_10_big(result);
}
s21_big_decimal res;
init_s21_decimal(&res);
add_big(*result, Q, &res);
copy_bits(res, result);
if (!is_zero_big(R)) {
init_s21_decimal(value_1);
mul_10_big(&R);
copy_bits(R, value_1);
}
} while (!is_zero_big(R) && scaleDiv < 28);
set_scale_big(result, scaleDiv);
for (int i = 0; i < 7; i++) {
printf("%lX ", result->bits[i]);
}
printf("\n");
}
Run Code Online (Sandbox Code Playgroud)
uint64_t
在unsigned long
Linux 和 macOS 上,因为该类型unsigned long
有 64 位,因此不需要使用具有更大级别的类型,尽管unsigned long long
后面的类型也有 64 位。
在 Windows 上,uint64_t
无法进行类型定义,unsigned long
因为由于遗留原因,Microsoft 选择保留unsigned long
为 32 位类型,即使在其 64 位 ABI 上也是如此。
如果您需要处理大于 的数字4294967295
,则确实不应使用unsigned long
可能限制为 32 位的数字。使用uint64_t
恰好 64 位或unsigned long long
至少 64 位是正确的选择。uint64_t
可能并非在所有平台上都可用,但在您的目标上是可用的,并且您不太可能遇到不可用的平台。
uint64_t
对于您的目的而言,是否类型定义unsigned long
并不unsigned long long
重要,因为它始终是 64 位。
更改类型uint64_t
不是一个选项,因为在不同模块中使用不同的定义可能会出现潜在的未定义行为。
如果您在应用程序中一致地使用整数类型,那么uint64_t
在需要 64 位无符号类型的任何地方使用应该不会造成问题。
对于读取和打印,您可以使用以下中定义的标准宏<inttypes.h>
:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(int argc, char *argv[]) {
uint64_t x;
if (argc > 1 && sscanf(argv[1], "%"SCNu64"", &x) == 1) {
printf("%16"PRIx64"\n", x);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果您愿意,可以这样使用strtoull
and :printf
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[]) {
char buf[100];
uint64_t x;
if (argc > 1) {
x = strtoul(argv[1], NULL, 10);
printf("%16llx"\n", (unsigned long long)x);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您还可以将自己的类型定义u64_t
为unsigned long long
and use%llu
或%llx
inscanf
和printf
like 函数的 typedef,而无需额外的强制转换。
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long u64_t; // assuming 64-bit
int main(int argc, char *argv[]) {
u64_t x;
if (argc > 1 && sscanf(argv[1], "%llu", &x) == 1) {
printf("%16llx\n", x);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
或者您可以简单地unsigned long long
在任何地方使用。