如何创建一个(f)16重复n次的数字



我需要创建一个数字,其中(f(16重复n次。0<n<=16.

我尝试了以下例子,例如n=16

std::cout << "hi:" << std::hex << std::showbase << (1ULL << 64) - 1 << std::endl;

警告:移位计数>=类型的宽度[-Wshift计数溢出]std::cout<lt"嗨:"<lt;std::hex<lt;std::showbase<lt;(1ULL<<64(-1<lt;std::endl;^生成了~~1个警告。

hi:0x200

如何在不溢出ULL的情况下获得所有数字f

对于n=1到16,您可以从所有Fs开始,然后相应地移动:

0xFFFFFFFFFFFFFFFFULL >> (4*(16-n));

(单独处理n=0(

其中(f(16重复n次。

如果我理解正确,我相信这是微不足道的。添加一个f。将数字向左移动4位。添加另一个f。向左移动4位。添加另一个f。重复n次。

#include <stdio.h>
unsigned long long gen(unsigned n) {
unsigned long long r = 0;
while (n--) {
r <<= 4;
r |= 0xf;
}
return r;
}
int main() {
for (int i = 0; i < 16; ++i) {
printf("%d -> %llxn", i, gen(i));
}
}

输出:

0 -> 0
1 -> f
2 -> ff
3 -> fff
4 -> ffff
5 -> fffff
6 -> ffffff
7 -> fffffff
8 -> ffffffff
9 -> fffffffff
10 -> ffffffffff
11 -> fffffffffff
12 -> ffffffffffff
13 -> fffffffffffff
14 -> ffffffffffffff
15 -> fffffffffffffff

如果n是16位,unsigned long long是64位,则按4*n位移位是有问题的,因此可以通过较小的移位量来解决问题。如果已知n是正的,我们可以将其划分为两个移位:

(1ull << 4 << 4*(n-1)) - 1u

而且,由于1ull << 4是一个常数,我们可以替换它:

(0x10ull << 4*(n-1)) - 1u

如果n可以为零,那么,为了支持从0到16的任何值,我们不能使用单个表达式。一个解决方案是:

n ? 0 : (0x10ull << 4*(n-1)) - 1u

如果您只以十六进制格式和数字f进行询问,请使用其他答案。

下面的函数可以为十六进制和十进制格式以及任何数字生成数字。

#include <iostream>
uint64_t getNum(uint64_t digit, uint64_t times, uint64_t base)
{
if (base != 10 && base != 16) return 0;
if (digit >= base) return 0;

uint64_t res = 0;
uint64_t multiply = 1;
for(uint64_t i = 0; i < times; ++i)
{
res += digit * multiply;
multiply *= base;
}
return res;
}
int main() {
std::cout << getNum(3, 7, 10) << std::endl;
std::cout << std::hex << getNum(0xa, 14, 16) << std::dec << std::endl;
return 0;
}

输出:

3333333
aaaaaaaaaaaaaa

注意:当前代码没有溢出检测。

您可以编写一个单独的函数,例如以下方式。

#include <stdio.h>
unsigned long long create_hex( size_t n )
{
unsigned long long x = 0;

n %= 2 * sizeof( unsigned long long );
while ( n-- )
{
x = x << 4 | 0xf;
}

return x;
}
int main( void ) 
{
for ( size_t i = 0; i <= 16; i++ )
{
printf( "%zu -> %llxn", i, create_hex( i ) );
}
}   

程序输出为

0 -> 0
1 -> f
2 -> ff
3 -> fff
4 -> ffff
5 -> fffff
6 -> ffffff
7 -> fffffff
8 -> ffffffff
9 -> fffffffff
10 -> ffffffffff
11 -> fffffffffff
12 -> ffffffffffff
13 -> fffffffffffff
14 -> ffffffffffffff
15 -> fffffffffffffff
16 -> 0

由于最初使用的是C和C++两种语言标记,因此要将此程序作为C++程序运行,请将头<stdio.h>替换为<iostream>,并使用运算符<lt;而不是CCD_ 16的调用。

最新更新