英文:
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

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;
}
- 由于任务不使用有符号值,考虑使用
unsigned和unsigned long long。 
英文:
- 
Make certain the right-hand side of the
=uses wide enough math. OP's code, as is, may riskintoverflow.intis not certainly wide enough for 12 decimal digit math.long longgood for at least 18 decimal digits. - 
Assign the result to a wide enough type too. Use
long longconstants to coax the math intolong 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 
unsignedandunsigned 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("%llu\n", id);
printf("%llu\n", extract(id, 4, 7));
}
You need to add some parameter checks (to see if they are valid)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论