Có một sự khác biệt quan trọng giữa std::min
, std::max
và fmin
và fmax
.
std::min(-0.0,0.0) = -0.0
std::max(-0.0,0.0) = -0.0
trong khi
fmin(-0.0, 0.0) = -0.0
fmax(-0.0, 0.0) = 0.0
Vì vậy std::min
không thể thay thế 1-1 cho fmin
. Các hàm std::min
và std::max
không giao hoán. Để có được kết quả tương tự với đôi với fmin
và fmax
ta nên trao đổi các đối số
fmin(-0.0, 0.0) = std::min(-0.0, 0.0)
fmax(-0.0, 0.0) = std::max(0.0, -0.0)
Nhưng như xa như tôi có thể nói all these functions are implementation defined anyway in this case như vậy để chắc chắn 100% bạn phải kiểm tra cách thức chúng được thực hiện.
Có một sự khác biệt quan trọng. Đối với x ! = NaN
:
std::max(Nan,x) = NaN
std::max(x,NaN) = x
std::min(Nan,x) = NaN
std::min(x,NaN) = x
trong khi
fmax(Nan,x) = x
fmax(x,NaN) = x
fmin(Nan,x) = x
fmin(x,NaN) = x
fmax
có thể được mô phỏng với đoạn mã sau
double myfmax(double x, double y)
{
// z > nan for z != nan is required by C the standard
int xnan = isnan(x), ynan = isnan(y);
if(xnan || ynan) {
if(xnan && !ynan) return y;
if(!xnan && ynan) return x;
return x;
}
// +0 > -0 is preferred by C the standard
if(x==0 && y==0) {
int xs = signbit(x), ys = signbit(y);
if(xs && !ys) return y;
if(!xs && ys) return x;
return x;
}
return std::max(x,y);
}
Điều này cho thấy std::max
là một tập hợp con của fmax
.
Nhìn vào hội đồng cho thấy rằng Clang sử dụng mã dựng sẵn cho fmax
và fmin
trong khi GCC gọi chúng từ thư viện toán học.Việc lắp ráp cho vang cho fmax
với -O3
là
movapd xmm2, xmm0
cmpunordsd xmm2, xmm2
movapd xmm3, xmm2
andpd xmm3, xmm1
maxsd xmm1, xmm0
andnpd xmm2, xmm1
orpd xmm2, xmm3
movapd xmm0, xmm2
trong khi cho std::max(double, double)
nó chỉ đơn giản là
maxsd xmm0, xmm1
Tuy nhiên, đối với GCC và Clang sử dụng -Ofast
fmax
đơn giản trở nên
maxsd xmm0, xmm1
Vì vậy, chương trình này một lần nữa rằng std::max
là một tập con của fmax
và khi bạn sử dụng một mô hình điểm động lỏng lẻo không có số nan
hoặc số 0 thì fmax
và std::max
là giống nhau. Cùng một đối số rõ ràng áp dụng cho fmin
và std::min
.
Cảnh báo: tối thiểu và tối đa chỉ có thể so sánh hai biến của cùng một loại chính xác ... vì vậy bạn không thể so sánh số int và số double với chúng: ( –
True - max (1, 2.0) không hoạt động, nó có để được một cái gì đó như tối đa (1, 2.0) hoặc tối đa (gấp đôi (1), 2.0) –
Đó là một điều tốt ™ IMO :) – Cogwheel