为什么不能在内核中使用科学记数法
Why can't you use scientific notation in kernel
我正在尝试编写内核 (4.8.1) 模块,如果我使用
if (hrtimer_cancel(&hr_timer) == 1) {
u64 remaining = ktime_to_ns(hrtimer_get_remaining(&hr_timer));
printk("(%llu ns; %llu us)\n", remaining,
(unsigned long long) (remaining/1e3));
}
它引发了这个错误
error: SSE register return with SSE disabled
printk("\t\t(%llu ns; %llu us)\n",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
remaining,
~~~~~~~~~~
(unsigned long long) (remaining/1e3));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
而如果我使用
if (hrtimer_cancel(&hr_timer) == 1) {
u64 remaining = ktime_to_ns(hrtimer_get_remaining(&hr_timer));
printk("(%llu ns; %llu us)\n", remaining,
(unsigned long long) (remaining/1000));
}
它没有问题。
那么为什么不能在内核中使用科学计数法呢?我的意思是,我认为使用 1e3; 1e6; 1e9
而不是 1000; 1000000; 1000000000
.
更容易和更易读
只是portability/robustness的问题吗?
或者类似的东西(在这种情况下)
You need ns? Use ktime_to_ns
You need us? Use ktime_to_us
You need ms? Use ktime_to_ms
P.S。我尝试了一个简单的 .c 程序,它没有问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void error_handler(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
unsigned long parse_num(const char *number)
{
unsigned long v;
char *p;
errno = 0;
v = strtoul(number, &p, 10);
if (errno != 0 || *p != '[=13=]')
error_handler("parse_num | strtoul");
return v;
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s number_greater_than_1000\n", argv[0]);
return EXIT_FAILURE;
}
unsigned long number = parse_num(argv[1]);
if (number < 1e3 || number > 1e6)
{
fprintf(stderr, "Need to be a number in range (%lu, %lu)\n", (unsigned long) 1e3, (unsigned long) 1e6);
return EXIT_FAILURE;
}
printf("Original: %lu\tScaled: %lu\n", number, (unsigned long) (number/1e3));
return EXIT_SUCCESS;
}
1e3
不 等同于 1000
.
1000
是 int
类型的整型常量。 1e3
是一个 double
类型的浮点常量,等价于 1000.0
。这使得 remaining/1e3
成为浮点除法,这正是编译器所抱怨的。
另见 SSE register return with SSE disabled。
我正在尝试编写内核 (4.8.1) 模块,如果我使用
if (hrtimer_cancel(&hr_timer) == 1) {
u64 remaining = ktime_to_ns(hrtimer_get_remaining(&hr_timer));
printk("(%llu ns; %llu us)\n", remaining,
(unsigned long long) (remaining/1e3));
}
它引发了这个错误
error: SSE register return with SSE disabled
printk("\t\t(%llu ns; %llu us)\n",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
remaining,
~~~~~~~~~~
(unsigned long long) (remaining/1e3));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
而如果我使用
if (hrtimer_cancel(&hr_timer) == 1) {
u64 remaining = ktime_to_ns(hrtimer_get_remaining(&hr_timer));
printk("(%llu ns; %llu us)\n", remaining,
(unsigned long long) (remaining/1000));
}
它没有问题。
那么为什么不能在内核中使用科学计数法呢?我的意思是,我认为使用 1e3; 1e6; 1e9
而不是 1000; 1000000; 1000000000
.
只是portability/robustness的问题吗?
或者类似的东西(在这种情况下)
You need ns? Use
ktime_to_ns
You need us? Usektime_to_us
You need ms? Usektime_to_ms
P.S。我尝试了一个简单的 .c 程序,它没有问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void error_handler(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
unsigned long parse_num(const char *number)
{
unsigned long v;
char *p;
errno = 0;
v = strtoul(number, &p, 10);
if (errno != 0 || *p != '[=13=]')
error_handler("parse_num | strtoul");
return v;
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s number_greater_than_1000\n", argv[0]);
return EXIT_FAILURE;
}
unsigned long number = parse_num(argv[1]);
if (number < 1e3 || number > 1e6)
{
fprintf(stderr, "Need to be a number in range (%lu, %lu)\n", (unsigned long) 1e3, (unsigned long) 1e6);
return EXIT_FAILURE;
}
printf("Original: %lu\tScaled: %lu\n", number, (unsigned long) (number/1e3));
return EXIT_SUCCESS;
}
1e3
不 等同于 1000
.
1000
是 int
类型的整型常量。 1e3
是一个 double
类型的浮点常量,等价于 1000.0
。这使得 remaining/1e3
成为浮点除法,这正是编译器所抱怨的。
另见 SSE register return with SSE disabled。