英文:
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 riskint
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 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
unsigned
andunsigned 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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论