All | _ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
fabs, fabsf, fabsl – расчет абсолютного значения
double fabs (double x);
float fabsf (float x);
long double fabsl (long double x);
i – число с плавающей точкой, абсолютное значение которого требуется рассчитать.
Абсолютное значение аргумента функции.
Функции рассчитывают абсолютное значение (модуль) числа с плавающей точкой.
Причем в функции fabsf аргумент для расчета и возвращаемое значение задаются числами с плавающей точкой (тип float, точность не менее шести значащих десятичных цифр, разрядность — 32).
В функции fabs аргумент и возвращаемое значение задаются числами с плавающей точкой двойной точности (тип double, точность не менее десяти значащих десятичных цифр, разрядность — 64).
В функции fabsl аргумент и возвращаемое значение задаются числами с плавающей точкой повышенной точности (тип long double, точность не менее десяти значащих десятичных цифр, разрядность — 80).
В примере рассчитывается модуль числа -612367.54783 с помощью функций fabs, fabsf и fabsl, и результат выводится на консоль. Обратите внимание, что точности функции fabsf не достаточно для получения верного решения.
Аргумент: -612367.54783
fabsf : 612367.56250
fabs : 612367.54783
fabsl : 612367.54783
Я проверил разницу между abs и fabs на python здесь
Как я понимаю, есть некоторые различия в скорости и переданных типах, но мой вопрос связан с родным c++ на V.S.
Относительно V.S. Я попробовал следующее на Visual Studio 2013 (v120) :
Итак fabs(-9) он даст мне ошибку компилятора, но когда я попытался сделать следующее:
Что я понимаю из первого кода, который он не будет компилировать, потому что fabs(-9) нужен двойной, и компилятор не смог преобразовать -9 в -9.0, но во втором коде компилятор преобразует i=-9 в i=-9.0 во время компиляции, поэтому fabs(i) будет работать нормально.
Любое лучшее объяснение?
Другое дело, почему компилятор не может принять fabs(-9) и преобразовать значение int в ****** автоматически, как то, что у нас есть в С#?
В С++ std::abs перегружается как для типов с целыми числами, так и с плавающей точкой. std::fabs работает только с типами с плавающей запятой (pre С++ 11). Обратите внимание, что значение std:: важно, функция C ::abs , которая обычно доступна по наследству, будет обрабатывать только int !
не означает, что преобразование из int (тип -9 ) в ****** отсутствует, но компилятор не знает, какое преобразование для выбора ( int → float , ****** , long ****** ), так как для каждого из этих трех существует a std::fabs . В вашем обходном пути явное указание компилятору использовать преобразование int → ****** , поэтому неопределенность исчезает.
С++ 11 решает это, добавляя ****** fabs( Integral arg ); , который вернет abs любого целочисленного типа, преобразованного в ****** . По-видимому, эта перегрузка также доступна в режиме С++ 98 с libstdС++ и libС++.
В общем, просто используйте std::abs , он пойдет правильно. (Интересная ловушка, отмеченная @Shafik Yaghmour. Беззнаковые целые типы делают смешные вещи на С++.)
I checked the difference between abs and fabs on python here
As I understand there are some difference regarding the speed and the passed types, but my question related to native c++ on V.S.
Regarding the V.S. I tried the following on Visual Studio 2013 (v120) :
So fabs(-9) it will give me a compiler error, but when I tried to do the following:
What I understand from the first code that it will not compile because fabs(-9) need a double, and the compiler could not convert -9 to -9.0, but in the second code the compiler will convert i=-9 to i=-9.0 at compile time so fabs(i) will work fine.
Any better explanation?
Another thing, why the compiler can’t accept fabs(-9) and convert the int value to double automatically like what we have in c#?
3 Answers 3
In C++, std::abs is overloaded for both signed integer and floating point types. std::fabs only deals with floating point types (pre C++11). Note that the std:: is important, the C function ::abs that is commonly available for legacy reasons will only handle int !
The problem with
is not that there is no conversion from int (the type of -9 ) to double , but that the compiler does not know which conversion to pick ( int -> float , double , long double ) since there is a std::fabs for each of those three. Your workaround explicitly tells the compiler to use the int -> double conversion, so the ambiguity goes away.
C++11 solves this by adding double fabs( Integral arg ); which will return the abs of any integer type converted to double . Apparently, this overload is also available in C++98 mode with libstdc++ and libc++.
In general, just use std::abs , it will do the right thing. (Interesting pitfall pointed out by @Shafik Yaghmour. Unsigned integer types do funny things in C++.)
Источник: