- 主题:你们用std::fabs还是一律std::abs?
and why?
--
修改:DoorWay FROM 61.185.187.*
FROM 61.185.186.*
我觉得不论对double还是int,都直接用std::abs就行了。
为啥要有std::fabs,啥时候用呢?
【 在 allegro 的大作中提到: 】
: 大哥,这俩完全是不同的函数,你啥意思啊?
--
FROM 61.185.187.*
查了和你说法相关、但又不同的说法。没有想明白。
“但是abs存在有整形重载版本,所以在会输入整形的时候,abs触发整形提升和转换”
这句是笔误吧,还是含着深意?如果有 int std::abs(int) 的重载,输入整形,怎么会提升转换?
又读了cppreference,
-------------------
For integral arguments, the integral overloads of std::abs are likely better matches. If std::abs is called with an unsigned integral argument that cannot be converted to int by integral promotion, the program is ill-formed
-------------------
unsigned int正值范围比int大一半,你说的uint 向 int 的promotion?
【 在 KillnCov 的大作中提到: 】
: 建议一律用fabs。
: 如果输入是浮点数,两者没有区别。
: 但是abs存在有整形重载版本,所以在会输入整形的时候,abs触发整形提升和转换,这中间就可能会产生不可预知的行为,反正C++标准说了,不保证不出异常。
: ...................
--
FROM 61.185.187.*
对,我查Stack Overflow上说,这个std::abs和abs是两套东西。c的abs,只支持int
cppreference的std::abs页面上Defect reports说,
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR LWG 2192
Applied to C++98
Behavior as published overloads of std::abs were inconsistently declared in two headers -- 这是说定义不致 <cmath> <cstdlib>
Correct behavior declared these overloads in both headers
另一个页面,std::fabs,说
DR LWG 2735
Applied to C++11
Behavior as published overloads of std::abs for integer types returning double was erroneously required -- 这是说 double fabs(int),进int出double,易错。
Correct behavior removed the requirement
https://en.cppreference.com/w/cpp/numeric/math/abs
https://en.cppreference.com/w/cpp/numeric/math/fabs
琢磨来琢磨去,我觉得 abs , std::abs留给整型, fabs()留给float/double最佳实践。
至于abs支持float/double,应该是第一个Defect Report引入的bug。
【 在 origin008 的大作中提到: 】
: 有的编译器,abs就自动int了
: 很久以前遇到过这个问题
: 不过那个时候还没用std::这么高级的货
: ...................
--
FROM 61.185.187.*
谢谢花宝贵的时间来验证。
我在另一楼的结论:
我琢磨来琢磨去,我觉得 abs , std::abs留给整型, fabs()留给float/double最佳实践。
至于abs支持float/double,应该是第一个Defect Report引入的bug。
【 在 easior 的大作中提到: 】
: 试了一下 MSVC++ 17、GCC 11 与 Apple Clang 11,
: 发现std::abs的行为各不相同:
: GCC 遵从重载的准确匹配原则;
: ...................
--
FROM 61.185.187.*
仿个笑话: 结婚前,真不知道连把牛奶放回冰箱,都有这么多种错法;——
用cpp编程之前,不知道求个绝对值都有这么多种错法。
--
FROM 61.185.187.*
不懂你的意思啊。可能我
“C++ 只有一个绝对值,那就是std::abs” -- 这是什么意思?std::fabs也是标准库提供的啊——你是有什么特殊的考虑吗?
"缺陷报告(defect report)的解决方案..." -- 这个我理解是,定义不一致的问题,c++11已经修复了。但引入了新问题, 即fabs进int出double的问题。不知那个 Apply To是这样理解的不,我是强行阅读,理解有点费劲哈。
“至于你说的最佳实现,那是C的方式” -- 我基本没用过C,一直倾向使用带std的与C划清界限。我的说最佳实【践】,是指使用带std::前缀的函数时,整型用std::abs,float/double用std::fabs。 这个主张我觉得挺好的,——刚注意这问题,考虑可能不全面。
【 在 easior 的大作中提到: 】
: 不认同你的说法,C++ 只有一个绝对值,那就是std::abs
: 缺陷报告(defect report)的解决方案里说了,
: 既然cmath、cstdlib里abs不一致,
: ...................
--
修改:DoorWay FROM 61.185.187.*
FROM 61.185.187.*
get. 重载,简洁。有实际使用的考虑。 有价值的观点。
嘲笑理解为自嘲,:-) 文字传达情绪失误。我讲那个笑话没有恶意,类似程序员自称码农,
是假定这里都是用cpp的好汉。当然别人叫我码农就怪怪的。再说我也只会用cpp,没有抽自己底的动机哈~
【 在 easior 的大作中提到: 】
: 就个人理解,std:fabs、std::fabsl、std::fabsf 之类的存在,只为兼容 C 的古典语法。
: 既然 C++ 有重载机制,一个 std::abs 就足以干所有的活了,非常简明。
: 当然这一切取决于标准怎么说,不同的编译器有不同的扩展,
: ...................
--
FROM 61.185.187.*
另外,Apple Clang,和 cpprefrence页面上的选项,Clang 5,是一回事吗?
还是类似 Chrominum 和 Chrome?
【 在 easior 的大作中提到: 】
: 就个人理解,std:fabs、std::fabsl、std::fabsf 之类的存在,只为兼容 C 的古典语法。
: 既然 C++ 有重载机制,一个 std::abs 就足以干所有的活了,非常简明。
: 当然这一切取决于标准怎么说,不同的编译器有不同的扩展,
: ...................
--
FROM 61.185.187.*
总结你我easior的观点,五个维度:
正确: 行为统一,比如不要double截成float函数行为不要出错,没有溢出等。
统一: 形式统一,都用 std::abs(或者哪一种)。通过重载提供。
清晰: 使用者与读者,清楚入参类型与返回类型。
方便: 标准库里提供。
简洁: 短的好。
结合下来,应该是标准库提供个模板函数, 进去T,出来T。并规定实现。
当来我不是数值计算专家,不知有没有进去T1,出来T2的个性需求。
---
类似的问题还有PI.
我看reddit讨论17/20标准,都是std要不要包含vector3d matrix 类了。
正: 要包含。使用方便,不用每次着急忙慌的包含头文件、手撸一个struct{x,y z}
反: 不包含。你无法选择一个最佳实【现】。标准库提供一个“低”效的实现,会传染、拉低其它更优实现。
我认为这是个标准库标到哪里的问题,容易争议。
原因是标准库名字起的太大,标准。叫实用库,或者Util库,就没有这种思辨负担了。
我支持加。办法比如,扶正boost库的地位;再发展boost库的对等库,实用库1,实用库2,实用库3……
另外俩众所周知的因素:1 cpp要兼容旧代码的包袱 2 语言的零负担设计原则:zero-overhead principle: What you don't use, you don't pay for。
也是cpp发展到如今局面的因素。其实退一步看,语言的作用还是太有限了。还有硬件、操作系统啥的。
【 在 origin008 的大作中提到: 】
: 在自己的头文件上,加个abs模板函数处理各种特化情况是不是更好?
--
FROM 61.185.158.*