rubi quitacementos quitacemento quita mexico limpiador home empresa donde comprar cemento catalogo ruby floating-point negative-number

quitacementos - ¿Cómo puedo limpiar de manera eficiente el flotador de cero negativo de Ruby?



rubi rc 10 quitacementos mexico (5)

En realidad, hay una solución que no requiere una condición.

def clean_output(value) value + 0 end

salida:

> clean_output(3.0) => 3.0 > clean_output(-3.0) => -3.0 > clean_output(-0.0) => 0.0

En realidad, no me gusta esta solución mejor que la que acepté, debido a la falta de claridad. Si lo viera en un fragmento de código que no escribí, me preguntaría por qué querría agregar cero a todo.

Aunque resuelve el problema, así que pensé que lo compartiría aquí de todos modos.

En Ruby, 0.0 * -1 == -0.0 .

Tengo una aplicación donde multiplico un montón de objetos Float con -1 , pero no me gusta el -0.0 en la salida, ya que es confuso.

¿Hay una forma inteligente de hacer que la salida de Float#to_s 0.0 lugar de -0.0 ?

Estoy completamente bien con la ejecución de cada objeto Float través de algún tipo de método scrubber / helper, pero lo siguiente tiende a confundirme aún más:

def clean_output(amount) if amount.zero? 0.0 else amount end end

ACTUALIZAR:

Para ser más precisos en lo que estoy buscando, quiero una solución que pueda ejecutar en un montón de flotadores, algunos de los cuales serán negativos, otros positivos. Los negativos deben permanecer negativos a menos que sean ceros negativos, es decir, -0.0 .

Ejemplos:

clean_output(-0.0) #=> 0.0 clean_output(-3.0) #=> -3.0 clean_output(3.0) #=> 3.0


No puedo pensar en nada mejor que eso:

def clean_output(value) value.nonzero? || value.abs end

pero eso es sólo una variación de su solución. Sin embargo, a diferencia del suyo, este no cambia el tipo de value (si, por ejemplo, pasa -0 , devolverá 0 ). Pero parece que no es importante en tu caso.

Si está seguro de que su código estará más limpio, puede agregar un método como ese a la clase Numeric (que hará que ese método esté disponible para Float , Fixnum y otras clases numéricas):

class Numeric def clean_to_s (nonzero? || abs).to_s end end

y luego usarlo:

-0.0.clean_to_s # => ''0.0'' -3.0.clean_to_s # => ''-3.0'' # same method for Fixnum''s as a bonus -0.clean_to_s # => ''0''

Eso hará que sea más fácil procesar una serie de flotadores:

[-0.0, -3.0, 0.0, -0].map &:clean_to_s # => ["0.0", "-3.0", "0.0", "0"]


Para mí, la intención de este código es un poco más clara y, al menos en Ruby 1.9.3, es un poco más rápida que @la Tin Man''s

def clean_output4(amount) amount.zero? ? 0.0 : amount end user system total real clean_output: 0.860000 0.000000 0.860000 ( 0.859446) clean_output4: 0.830000 0.000000 0.830000 ( 0.837595)


Si el código que escribiste te confunde, entonces esto debería realmente cambiar tu mente:

def clean_output(amount) amount.zero? && 0.0 || amount end

Con alguna prueba:

irb(main):005:0> f = 0.0 => 0.0 irb(main):006:0> f.zero? && 0.0 || f => 0.0 irb(main):007:0> f = -0.0 => -0.0 irb(main):008:0> f.zero? && 0.0 || f => 0.0 irb(main):009:0> f=1.0 => 1.0 irb(main):010:0> f.zero? && 0.0 || f => 1.0

No me gusta usar el nonzero? Porque su caso de uso es un poco confuso. Es parte de Numeric pero los documentos muestran que se usó como parte de Comparable con el operador <=> . Además, prefiero probar una condición cero para este propósito porque parece más sencillo.

Y, aunque el código del OP puede aparecer detallado, este es otro de esos casos en los que la optimización prematura no da resultado:

require ''benchmark'' def clean_output(amount) if amount.zero? 0.0 else amount end end def clean_output2(amount) amount.zero? && 0.0 || amount end def clean_output3(value) value + 0 end class Numeric def clean_to_s (nonzero? || abs).to_s end end n = 5_000_000 Benchmark.bm(14) do |x| x.report( "clean_output:" ) { n.times { a = clean_output(-0.0) } } x.report( "clean_output2:" ) { n.times { a = clean_output2(-0.0) } } x.report( "clean_output3:" ) { n.times { a = clean_output3(-0.0) } } x.report( "clean_to_s:" ) { n.times { a = 0.0.clean_to_s } } end

Y los resultados:

ruby test.rb user system total real clean_output: 2.120000 0.000000 2.120000 ( 2.127556) clean_output2: 2.230000 0.000000 2.230000 ( 2.222796) clean_output3: 2.530000 0.000000 2.530000 ( 2.534189) clean_to_s: 7.200000 0.010000 7.210000 ( 7.200648) ruby test.rb user system total real clean_output: 2.120000 0.000000 2.120000 ( 2.122890) clean_output2: 2.200000 0.000000 2.200000 ( 2.203456) clean_output3: 2.540000 0.000000 2.540000 ( 2.533085) clean_to_s: 7.200000 0.010000 7.210000 ( 7.204332)

to_s una versión sin los to_s . Estos se ejecutaron en mi computadora portátil, que tiene varios años, por lo que los tiempos resultantes son más altos que los de las pruebas anteriores:

require ''benchmark'' def clean_output(amount) if amount.zero? 0.0 else amount end end def clean_output2(amount) amount.zero? && 0.0 || amount end def clean_output3(value) value + 0 end class Numeric def clean_to_s (nonzero? || abs).to_s end def clean_no_to_s nonzero? || abs end end n = 5_000_000 Benchmark.bm(14) do |x| x.report( "clean_output:" ) { n.times { a = clean_output(-0.0) } } x.report( "clean_output2:" ) { n.times { a = clean_output2(-0.0) } } x.report( "clean_output3:" ) { n.times { a = clean_output3(-0.0) } } x.report( "clean_to_s:" ) { n.times { a = -0.0.clean_to_s } } x.report( "clean_no_to_s:" ) { n.times { a = -0.0.clean_no_to_s } } end

Y los resultados:

ruby test.rb user system total real clean_output: 3.030000 0.000000 3.030000 ( 3.028541) clean_output2: 2.990000 0.010000 3.000000 ( 2.992095) clean_output3: 3.610000 0.000000 3.610000 ( 3.610988) clean_to_s: 8.710000 0.010000 8.720000 ( 8.718266) clean_no_to_s: 5.170000 0.000000 5.170000 ( 5.170987) ruby test.rb user system total real clean_output: 3.050000 0.000000 3.050000 ( 3.050175) clean_output2: 3.010000 0.010000 3.020000 ( 3.004055) clean_output3: 3.520000 0.000000 3.520000 ( 3.525969) clean_to_s: 8.710000 0.000000 8.710000 ( 8.710635) clean_no_to_s: 5.140000 0.010000 5.150000 ( 5.142462)

Para resolver lo que se estaba desacelerando non_zero? :

require ''benchmark'' n = 5_000_000 Benchmark.bm(9) do |x| x.report( "nonzero?:" ) { n.times { -0.0.nonzero? } } x.report( "abs:" ) { n.times { -0.0.abs } } x.report( "to_s:" ) { n.times { -0.0.to_s } } end

Con los resultados:

ruby test.rb user system total real nonzero?: 2.750000 0.000000 2.750000 ( 2.754931) abs: 2.570000 0.010000 2.580000 ( 2.569420) to_s: 4.690000 0.000000 4.690000 ( 4.687808) ruby test.rb user system total real nonzero?: 2.770000 0.000000 2.770000 ( 2.767523) abs: 2.570000 0.010000 2.580000 ( 2.569757) to_s: 4.670000 0.000000 4.670000 ( 4.678333)


simplemente verifique si la respuesta es cero y luego aplique abs al valor. Se convertirá -0.0 en 0.0

fl_num = -0.0 fl_num = fl_num.abs fl_num = 0.0