Ruby 圆形 float to_int 如果是整数

发布于 2024-07-25 15:11:59 字数 300 浏览 10 评论 0原文

在 ruby​​ 中,如果它是整数,我想将浮点数转换为 int。 例如,

a = 1.0
b = 2.5

a.to_int_if_whole # => 1
b.to_int_if_whole # => 2.5

基本上我试图避免在任何没有小数的数字上显示“.0”。 我正在寻找一种优雅(或内置)的方式来做

def to_int_if_whole(float)
  (float % 1 == 0) ? float.to_i : float
end

In ruby, I want to convert a float to an int if it's a whole number. For example

a = 1.0
b = 2.5

a.to_int_if_whole # => 1
b.to_int_if_whole # => 2.5

Basically I'm trying to avoid displaying ".0" on any number that doesn't have a decimal. I'm looking for an elegant (or built-in) way to do

def to_int_if_whole(float)
  (float % 1 == 0) ? float.to_i : float
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

疯狂的代价 2024-08-01 15:12:00

一种简单的方法是:

class Float
  def prettify
    to_i == self ? to_i : self
  end
end

那是因为:

irb> 1.0 == 1
=> true
irb> 1 == 1.0
=> true

那么你可以这样做:

irb> 1.0.prettify
=> 1

irb> 1.5.prettify
=> 1.5

One simple way to it would be:

class Float
  def prettify
    to_i == self ? to_i : self
  end
end

That's because:

irb> 1.0 == 1
=> true
irb> 1 == 1.0
=> true

Then you could do:

irb> 1.0.prettify
=> 1

irb> 1.5.prettify
=> 1.5
肤浅与狂妄 2024-08-01 15:12:00

一艘单班轮冲刺...

sprintf("%g", 5.0)
=> "5"

sprintf("%g", 5.5)
=> "5.5"

A one liner sprintf...

sprintf("%g", 5.0)
=> "5"

sprintf("%g", 5.5)
=> "5.5"
捶死心动 2024-08-01 15:12:00

这是最终按照我想要的方式工作的解决方案:

class Float
  alias_method(:original_to_s, :to_s) unless method_defined?(:original_to_s)

  def is_whole?
    self % 1 == 0
  end

  def to_s
    self.is_whole? ? self.to_i.to_s : self.original_to_s
  end
end

这样我可以在需要时更新 is_whole? 逻辑(我似乎 tadman 的逻辑是最复杂的),并且它确保在任何地方浮点输出到一个字符串(例如,以一种形式),它以我想要的方式显示(即末尾没有零)。

感谢大家的想法——他们真的很有帮助。

This is the solution that ended up working the way I want it to:

class Float
  alias_method(:original_to_s, :to_s) unless method_defined?(:original_to_s)

  def is_whole?
    self % 1 == 0
  end

  def to_s
    self.is_whole? ? self.to_i.to_s : self.original_to_s
  end
end

This way I can update the is_whole? logic (I seems like tadman's is the most sophisticated) if needed, and it ensures that anywhere a Float outputs to a string (eg, in a form) it appears the way I want it to (ie, no zeros on the end).

Thanks to everybody for your ideas - they really helped.

赴月观长安 2024-08-01 15:12:00

如果您使用的是 Rails,则可以使用带有选项 strip_insignificant_zeros 的帮助器 number_to_rounded,例如:

ActiveSupport::NumberHelper.number_to_rounded(42.0, strip_insignificant_zeros: true)

或如下所示:

42.0.to_s(:rounded, strip_insignificant_zeros: true)

If you are using rails you can use helper number_to_rounded with option strip_insignificant_zeros, for example:

ActiveSupport::NumberHelper.number_to_rounded(42.0, strip_insignificant_zeros: true)

or like this:

42.0.to_s(:rounded, strip_insignificant_zeros: true)
飘落散花 2024-08-01 15:12:00

我对Ruby了解不多。

但这是一个显示问题。 如果您使用的库在将数字转换为字符串时没有办法格式化数字,我会感到非常惊讶。

可能没有一个包罗万象的格式化选项可以完全满足您的要求,但您可以设置一个方法,如果浮点是整数的浮点表示形式,则返回 true,否则返回 false。 在您创建的格式化例程中(因此您只需在一次位置执行此操作)只需根据这是对还是错来更改格式。

这里讨论如何控制显示数字时小数点后出现的位数。

注意浮点表示的复杂性。 数学可能会说答案是 3,但您可能会得到 3.000000000000000000001。 我建议使用增量来查看该数字是否几乎是整数。

I'm don't know much about Ruby.

But this is a display issue. I would be extremely surprised if the libraries you are using don't have a way to format a number when you convert it to a string.

There might not be a catch-all formatting option that does exactly what you want but you could set up a method that returns true if the float is the float representation of a whole number and false otherwise. Inside a formatting routine that you create (so you only have to do this in once place) just change the formatting based on if this is true or false.

This discusses how to control the number of digits that appear after the decimal when displaying a number.

Watch out for the intricacies of floating point representations. Math might say the answer is 3 but you may get 3.000000000000000000001. I'd suggest using a delta to see if the number is almost an integer number.

塔塔猫 2024-08-01 15:12:00

虽然我倾向于同意上面的帖子,但如果你必须这样做:

(float == float.floor) ? float.to_i : float

Although I'd tend to agree with the above post, if you must do this:

(float == float.floor) ? float.to_i : float
沩ん囻菔务 2024-08-01 15:12:00

这是我为教育目的提供的可怕的 hacktastic 实现:

class Float
  def to_int_if_whole(precision = 2)
    ("%.#{precision}f" % self).split(/\./).last == '0' * precision and self.to_i or self
  end
end

puts 1.0.to_int_if_whole # => 1
puts 2.5.to_int_if_whole # => 2.5
puts 1.9999999999999999999923.to_int_if_whole # => 2

使用 sprintf 样式调用的原因是它比 Float#round 方法更可靠地处理浮点近似。

Here's my horribly hacktastic implementation provided for educational purposes:

class Float
  def to_int_if_whole(precision = 2)
    ("%.#{precision}f" % self).split(/\./).last == '0' * precision and self.to_i or self
  end
end

puts 1.0.to_int_if_whole # => 1
puts 2.5.to_int_if_whole # => 2.5
puts 1.9999999999999999999923.to_int_if_whole # => 2

The reason for using the sprintf-style call is that it handles floating point approximations much more reliably than the Float#round method tends to.

甜心小果奶 2024-08-01 15:12:00

我对Ruby也不太了解。

但在 C++ 中,我会这样做:

bool IsWholeNumber( float f )
{
    const float delta = 0.0001;
    int i = (int) f;
    return (f - (float)i) < delta;
}

然后我会基于此格式化输出精度。

I don't know much about Ruby either.

But in C++, I'd do this:

bool IsWholeNumber( float f )
{
    const float delta = 0.0001;
    int i = (int) f;
    return (f - (float)i) < delta;
}

And then I'd format the output precision based on that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文