c++ - que - Cross plataforma/compilador sprintf consistente de números de coma flotante




que es coma flotante en informatica (3)

La respuesta más votada es incorrecta, porque la documentación es incorrecta en primer lugar.

Esto es lo que está sucediendo en LuaJIT:

#define lua_number2str(s,n)sprintf((s),"%.14g",(n))
#define lua_str2number(s,p)strtod((s),(p))

En tostring implementación de tonumber y tostring , esas son las macros llamadas para obtener los resultados.

No dude en corregir esta respuesta si encuentra la verdadera implementación "incorporada", porque también tengo curiosidad por saber cómo funciona realmente.

Tenemos un juego que debe ser determinista ya que es parte de su modelo multijugador. También usamos Lua, que usa el sprintf internamente (el formato es %.14g ).

El problema surge cuando imprime un número como 0.00001. En algunos casos imprime 1e-05 y en algunos otros casos, imprime 1e-005 (cero adicional).

Por ejemplo, cuando se compila con Visual Studio 2015 imprime 1e-005 , y con Visual Studio 2013 imprime 1e-05 . Intenté diferentes ajustes de configuración regional, pero parece que no tiene ningún efecto.

La pregunta es: ¿Cuál es la mejor solución para lograr resultados deterministas? Realmente no me importa si la notación científica está estandarizada o eliminada.

Soluciones en las que pensé:

  • Cuando uso la notación %f , no ignora los ceros insignificantes, por lo que tener %.14f resultaría en números demasiado largos.
  • Uso del método sprintf personalizado (copia pegada de algunas de las bibliotecas estándar)
  • Utilicé un formato especial en el que no pensé (solo uso esto como referencia: http://www.cplusplus.com/reference/cstdio/printf/ )

Lua te da math.frexp en la biblioteca estándar. Puede usar esto para dividir sus flotantes en forma de exponente y mantisa, y luego hacer una impresión personalizada en Lua puro que no dependerá de la plataforma subyacente. Aquí hay un ejemplo:

m,e = math.frexp(val)
io.write(m)
io.write('E')
io.write(e)

PD: Disfrutando los hechos del viernes, sigan viniendo :)


Un año después, así es como lo resolvimos.

Descargamos la implementación de impresión personalizada (trío) y el uso forzado de esta implementación en lugar del sistema uno en el lua (y nuestras fuentes).

También tuvimos que cambiar

long double trio_long_double_t;

a

double trio_long_double_t;

en el triodef.h para garantizar que Visual Studio y linux / mac den los mismos resultados.