在C语言中,不使用逻辑运算符就可以组合数字并得到里面的数字

nbysray5  于 2023-03-12  发布在  其他
关注(0)|答案(2)|浏览(95)

问题信息

禁止使用逻辑运算符、关系运算符、布尔变量或选择构造
我试着这样创建数字:

int year_diff = grad_year - start_year;
int prog_years = year_diff % 100;
int uniq_id = student_id % 10000;
int id_num = start_year * 100000000 + program_num * 1000000 + prog_years * 10000 + uniq_id;

把这些数字像这样

int loc_diff = loc2 - loc1;
int div = pow(10, loc1 - 1);
int desired_digits = (id_num / div) % (int) pow(10, loc_diff + 1);

但是它不起作用,我真的很困难。有人能帮忙吗

bqucvtff

bqucvtff1#

  • 确保=的右侧使用足够宽的数学运算。OP的代码可能存在int溢出的风险。int对于12位十进制数字的数学运算来说肯定不够宽。long long对于至少18位十进制数字来说是好的。
  • 把结果赋给一个足够宽的类型,使用long long常量把数学运算变成long long
// int id_num = start_year * 100000000 + program_num * 1000000 + prog_years * 10000 + uniq_id;
long long id_num = start_year*100000000LL + program_num*1000000LL + prog_years*10000LL + uniq_id;

...
// int desired_digits = (id_num / div) % (int) pow(10, loc_diff + 1);
long long desired_digits = (id_num / div) % (long long) pow(10, loc_diff + 1);
  • 考虑使用整数替代pow()pow()在转换为整数类型时会面临“相差1”或更多的风险。整数问题应避免浮点运算。
// I assert this code also fulfills
// "Any use of logical operators, relational operators, bool variables, ... is prohibited"
// It may/may not also fulfill "or selection constructs".  Unclear what OP means by that.
// If `"selection" means `if, switch, _Generic`, then code does not use those.

long long ipowll(int base, unsigned exponent) {
  long long ibase = base;
  long long ipower = 1;
  while (exponent) {
    // This abbreviated code here does not check or prevent overflow.
    // Added tests needed for that.
    ipower *= (long long[2]) {1, ibase}[exponent % 2];
    ibase *= ibase;
    exponent /= 2;
  }
  return ipower;
}
  • 由于task不使用有符号值,请考虑使用unsignedunsigned long long
vjhs03f7

vjhs03f72#

unsigned long long upow(unsigned x)
{
    unsigned long long result = 1;
    while(x--) result *= 10;
    return result;
}

unsigned long long getID(unsigned sNum, unsigned yStart, unsigned yEnd, unsigned programe)
{
    return (yEnd - yStart) * upow(4) + 
           sNum + 
           (programe % 100) * upow(6) + 
           (yStart % 10000) * upow(8);
}

unsigned long long extract(unsigned long long num, unsigned start, unsigned end)
{
    num /= upow(start - 1);
    num %= upow(end - start + 1);
    return num;
}

int main(void)
{
    unsigned long long id = getID(1234, 2020, 2024, 78);
    printf("%llu\n", id);
    printf("%llu\n", extract(id, 4, 7));
}

您需要添加一些参数检查(以查看它们是否有效)

相关问题