C 中的强制转换是如何进行的?
我正在 leetcode 上解决问题,这是我的代码。
/*
max int 2147483647 (10^10)
max uint 4294967295 (10^10)
ULONG_MAX 18446744073709551615 (10^20)
LONG_MAX 9223372036854775807 (10^20)
USHRT_MAX 65535, SHRT_MAX 32767
*/
#include <stdio.h>
#include <math.h>
int main(void) {
int t;
scanf("%d", &t);
while (t--) {
int length;
scanf("%d", &length);
char string[length];
scanf("%s", string);
long int answer = 0;
int ones = 0;
for (int i = 0; i < length; i++) {
ones = ones + (string[i] == '1') * (i + 1);
if (ones & 1) {
answer = (answer + (long int)pow(2, length - (i + 1))) % 998244353;
}
}
printf("%ld\n", answer);
}
return 0;
}
它对于较小的值(可能是 int 可以保存的值)工作得很好。但是当计算大值时,它给出了意想不到的结果
,然后我认为这可能是由于溢出造成的,所以我将变量 int answer
更改为 long int answer
我认为这会解决这个问题问题,但它没有,而且还破坏了更小的值的代码
,然后我注意到我正在使用 pow
函数,它肯定会超出高长度值的限制,如 pow< /code> 给出双值作为回报,我将其转换为
int
与之前的 (int)pow(2, length - (i+1))
,我将其更改为 (long int)pow(2, length - (i+1))
我传递这些值来测试代码。
4
16
1111010010111101
2
10
6
101101
4
1111
预期的结果是,
49359
3
48
12
但我得到了
49359
65535
49152
49152
当我使用 int answer
和 (int)pow(...)
时,我得到了预期的结果,但如果我投射答案或 pow长久以来,我得到了意想不到的结果。我不确定这是否是由于强制转换或其他原因造成的,但据我所知,只有当我将这些变量强制转换为 long 时才会发生这种情况。
I was solving a problem on leetcode and this was my code.
/*
max int 2147483647 (10^10)
max uint 4294967295 (10^10)
ULONG_MAX 18446744073709551615 (10^20)
LONG_MAX 9223372036854775807 (10^20)
USHRT_MAX 65535, SHRT_MAX 32767
*/
#include <stdio.h>
#include <math.h>
int main(void) {
int t;
scanf("%d", &t);
while (t--) {
int length;
scanf("%d", &length);
char string[length];
scanf("%s", string);
long int answer = 0;
int ones = 0;
for (int i = 0; i < length; i++) {
ones = ones + (string[i] == '1') * (i + 1);
if (ones & 1) {
answer = (answer + (long int)pow(2, length - (i + 1))) % 998244353;
}
}
printf("%ld\n", answer);
}
return 0;
}
It is working fine for smaller values (possibly values that int can hold). but when calculating large values it was giving unexpected result
then I thought that might be due to the overflow so I changed variable int answer
to long int answer
which I thought will resolve the problem, but it didn't and also broke the code for even smaller values
then I noticed I am using pow
function which will for sure exceed the limit for high values of length, As pow
gives double value in return, I was casting it to an int
with (int)pow(2, length - (i+1))
before, which I changed to (long int)pow(2, length - (i+1))
I was passing these values to test the code.
4
16
1111010010111101
2
10
6
101101
4
1111
and expected result was
49359
3
48
12
but i got
49359
65535
49152
49152
I am getting the expected result when I am using int answer
and (int)pow(...)
but if I cast answer or pow to long, I am getting unexpected result. I am not sure if this is due to cast or something else but as far as I noticed it happens only when I am casting these variables into long.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
代码中存在多个问题:
t
值为负数,while (t--)
将导致意外行为。使用while (t-->0)
char string[length];
没有足够的空间容纳length
个字符,并且空终止符。使用char string[length + 1];
scanf("%s", string);
不提供任何针对缓冲区溢出的保护。没有简单的方法可以告诉scanf()
为%s
读取可变数量的字节。由于长度可能大到100000
,因此您可能应该从堆中分配数组并使用getchar()
读取这些位。循环中的代码似乎没有实现问题的解决方案:
<块引用>
给定一个二进制字符串
S
,她将字符串的美感定义为所有子字符串的十进制表示的按位异或>S
.这些说明具有误导性,因为结果与任何内容的十进制表示形式无关。但您的代码不会转换所有子字符串,仅应显示对
998244353
取模的结果。对模块应用异或会产生不同的结果。此外,不需要
pow
转换二进制表示:您可以将res
乘以 2,然后添加循环中下一个数字的值。要计算生成的位串,请考虑偏移量
i
处的位,从偏移量0
的字符串开头开始:它将与自身进行异或
i
次仅删除前缀的子字符串。然后,对于每个子字符串,索引
j
小于i
的每个位将与最后一个ij< 进行异或
j
次/code> 删除了一些位。如果
i
为奇数,则异或i
次将产生0
,因此与使用最后一位相反的掩码具有相同的效果我
。您可以为此使用 2 个嵌套循环:
这是修改后的版本:
There are multiple problems in the code:
while (t--)
will cause unexpected behavior if the value oft
entered is negative. Usewhile (t-- > 0)
char string[length];
does not have enough space forlength
characters and the null terminator. Usechar string[length + 1];
scanf("%s", string);
does not provide any protection against buffer overflow. There is no simple way to tellscanf()
to read up to a variable number of bytes for%s
. Since the length can be as large as100000
, you should probably allocate the array from the heap and read the bits withgetchar()
.the code in the loop does not seem to implement a solution for the problem:
The instructions are misleading because the result has nothing to do with the decimal representation of anything. But your code does not convert all substrings and only the result should be displayed modulo
998244353
. Applying xor to the modules would produce a different result.furthermore there is no need for
pow
to convert a binary representation: you can multiplyres
by 2 and add the value of the next digit in the loop.To compute the resulting bitstring, consider the bit at offset
i
, starting at the beginning of the string with offset0
:it will be XORed with itself
i
times for substrings with just a prefix removed.Then each bit with an index
j
smaller thani
will be XORedj
times for each substring with the lasti-j
bits removed.XORing
i
times will produce0
ifi
is odd, hence has the same effect as masking with the opposite of the last bit ofi
.You could use 2 nested loops for this:
Here is a modified version: