在C中,将数字组合并获取其中的数字,而不使用逻辑运算符。

huangapple go评论64阅读模式
英文:

In C combine numbers and get the numbers inside without logical operators

问题

使用逻辑运算符、关系运算符、布尔变量或选择结构都是禁止的。

我尝试像这样创建这个数字:

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);

但它没有起作用,我遇到了很大的困难。有人可以帮忙吗?

英文:

Problem info

在C中,将数字组合并获取其中的数字,而不使用逻辑运算符。

Any use of logical operators, relational operators, bool variables, or selection constructs is prohibited

I tried creating the number like this:

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;

and pulling out those numbers like this

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

but it is not working and I am having a really hard time. Can someone help

答案1

得分: 2

  • 确保等号右侧使用足够宽的数学类型。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()在转换为整数类型时可能存在“差一”的风险或更大。在解决整数问题时避免使用浮点数运算。
// 我断言这段代码也满足了
// “禁止使用逻辑运算符、关系运算符、bool变量…”
// 它可能/可能不满足“或选择结构”。不清楚OP的意思。
// 如果“选择”意味着“if、switch、_Generic”,那么代码不使用这些。

long long ipowll(int base, unsigned exponent) {
  long long ibase = base;
  long long ipower = 1;
  while (exponent) {
    // 此处的简化代码未检查或防止溢出。
    // 需要添加用于防止溢出的测试。
    ipower *= (long long[2]) {1, ibase}[exponent % 2];
    ibase *= ibase;
    exponent /= 2;
  }
  return ipower;
}
  • 由于任务不使用有符号值,考虑使用unsignedunsigned long long
英文:
  • Make certain the right-hand side of the = uses wide enough math. OP's code, as is, may risk int overflow. int is not certainly wide enough for 12 decimal digit math. long long good for at least 18 decimal digits.

  • Assign the result to a wide enough type too. Use long long constants to coax the math into 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);

  • Consider an integer alternative to pow(). pow() risks being "off-by-1" or more when converted to an integer type. Avoid floating point math for an integer problem.
// 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;
}
  • Since task does not use signed values, consider using unsigned and unsigned long long.

答案2

得分: 1

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

unsigned long long getID(unsigned sNum, unsigned yStart, unsigned yEnd, unsigned programe)
{
    // Check if yEnd is greater than yStart
    if (yEnd <= yStart) {
        return 0; // Invalid input, return a default value
    }

    unsigned long long id = (yEnd - yStart) * upow(4) +
                            sNum +
                            (programe % 100) * upow(6) +
                            (yStart % 10000) * upow(8);
    
    // Check if the resulting id is within the valid range
    if (id < 0 || id > 9999999999999999ULL) {
        return 0; // Invalid input, return a default value
    }
    
    return id;
}

unsigned long long extract(unsigned long long num, unsigned start, unsigned end)
{
    // Check if start and end are valid
    if (start <= 0 || end <= 0 || start > end) {
        return 0; // Invalid input, return a default value
    }
    
    num /= upow(start - 1);
    num %= upow(end - start + 1);
    return num;
}

int main(void)
{
    unsigned long long id = getID(1234, 2020, 2024, 78);
    if (id == 0) {
        printf("Invalid input.\n");
    } else {
        printf("%llu\n", id);
        unsigned long long extracted = extract(id, 4, 7);
        if (extracted == 0) {
            printf("Invalid extraction range.\n");
        } else {
            printf("%llu\n", extracted);
        }
    }
}

The code now includes parameter checks to ensure that the inputs are valid, and it returns appropriate values when the inputs are invalid.

英文:
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(&quot;%llu\n&quot;, id);
printf(&quot;%llu\n&quot;, extract(id, 4, 7));
}

You need to add some parameter checks (to see if they are valid)

huangapple
  • 本文由 发表于 2023年2月19日 02:14:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75495396.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定