Existe uma maneira de obter programaticamente o dobro que está mais próximo de 1.0, mas não é realmente 1.0?
Uma maneira rápida de fazer isso seria memorizar o dobro em um número inteiro do mesmo tamanho e, em seguida, subtrair um. Da forma como os formatos de ponto flutuante IEEE754 funcionam, isso acabaria diminuindo o expoente em um enquanto mudava a parte fracionária de todos os zeros (1.000000000000) para todos os uns (1.111111111111). No entanto, existem máquinas onde inteiros são armazenados little-endian, enquanto o ponto flutuante é armazenado big-endian, então isso nem sempre funciona.
c++
floating-point
floating-accuracy
Jorgbrown
fonte
fonte
nextafter()
é a única maneira adequada de conseguir o que deseja.1.0000...
binário é decrementado0.111111....
e, para normalizá-lo, você deve deslocá-lo para a esquerda: o1.11111...
que requer que você diminua o expoente. E então você está a 2 ulp de 1.0. Portanto, não, subtrair um do valor integral NÃO dá a você o que é perguntado aqui.Respostas:
Em C e C ++, o seguinte fornece o valor mais próximo de 1,0:
Observe, entretanto, que nas versões posteriores do C ++,
limits.h
foi substituído porclimits
. Mas então, se você estiver usando código específico C ++ de qualquer maneira, você pode usarE como Jarod42 escreveu em sua resposta, desde C99 ou C ++ 11 você também pode usar
nextafter
:É claro que em C ++ você pode (e para versões posteriores de C ++ deve) incluir
cmath
e usarstd::nextafter
.fonte
Desde C ++ 11, você pode usar
nextafter
para obter o próximo valor representável em determinada direção:Demo
fonte
std::ceil(std::nextafter(1., std::numeric_limits<double>::max()))
.nextafter
, e é assim que o musl o implementa, caso alguém mais queira ver como é feito. Basicamente: manipulação de bits brutos.Em C, você pode usar isto:
DBL_EPSILON
é a diferença entre 1 e o menor valor maior que 1 que é representável.Você precisará imprimi-lo com vários dígitos para ver o valor real.
Na minha plataforma,
printf("%.16lf",1.0+DBL_EPSILON)
dá1.0000000000000002
.fonte
1.
como1'000'000
demonstração1.0
. BTW, também dá o valor mais próximo maior que 1, e não o valor mais próximo absoluto de 1 (que é possivelmente menor que 1). Portanto, concordo que esta é uma resposta parcial, mas achei que poderia contribuir.Em C ++, você também pode usar este
fonte