jamelkenya.com

Exploring Ruby 3.3.0: The Curious Case of Rounding to Even

Written on

Chapter 1: Discovering Ruby's Updates

Today, as I was perusing the changelogs for major programming languages, frameworks, and libraries—something I frequently do—I noticed that some lacked significant updates. However, I eventually came across the changelogs for Ruby. In May, a preview version of Ruby 3.3.0 was made available, showcasing various performance enhancements.

Despite these improvements, the documentation leaves much to be desired. Some highlights include:

  • YJIT: Notable performance boosts compared to version 3.2
  • Enhanced support for splat and rest arguments
  • Stack operations for the virtual machine now allocate registers
  • Several methods, including Integer#!=, String#!=, Kernel#block_given?, Kernel#is_a?, Kernel#instance_of?, and Module#===, have received special optimizations
  • Instance variables no longer exit to the interpreter with megamorphic Object Shapes
  • Reduced memory usage for compiled code metadata
  • Improved code generation for ARM64 architecture

Due to the lack of detailed links, I delved into the commit history and discovered an intriguing change made in December 2022 by Kenta Murata to the numeric.c library. This piqued my interest since changes in mathematical modules are infrequent for good reason: the principles of mathematics themselves do not shift often.

Rounding: A Topic of Interest

Rounding numbers is a subject that resonates with me, especially since I wrote an article earlier this year discussing the absence of a standard rounding method across programming languages. Each language tends to handle rounding differently by default, although the underlying mathematical principles are generally consistent.

Yet, when computers perform rounding, the process can become quite complex. I understand that mathematics may not captivate everyone, but I find it fascinating. For example, I recently discovered that a sphere in the fifth dimension has the largest volume compared to spheres in other dimensions. This leads to the intriguing question of what makes the fifth dimension so unique.

So, why was it necessary to adjust Ruby's rounding function after appearing satisfactory for so long?

Chapter 2: The Revised Half-Round-Even Function

The final version of the modified half_round_even function consists of the following code:

static double round_half_even(double x, double s) {

double u, v, us, vs, f, d, uf;

v = modf(x, &u);

us = u * s;

vs = v * s;

if (x > 0.0) {

f = floor(vs);

uf = us + f;

d = vs - f;

if (d > 0.5) d = 1.0;

else if (d == 0.5 || ((double)((uf + 0.5) / s) <= x)) d = fmod(uf, 2.0);

else d = 0.0;

x = f + d;

} else if (x < 0.0) {

f = ceil(vs);

uf = us + f;

d = f - vs;

if (d > 0.5) d = 1.0;

else if (d == 0.5 || ((double)((uf - 0.5) / s) >= x)) d = fmod(-uf, 2.0);

else d = 0.0;

x = f - d;

}

return us + x;

}

Though it may appear concise at just 33 lines, it illustrates that rounding is far from straightforward. While using single or double-letter variable names may be frowned upon in higher-level programming, they serve a purpose in mathematical contexts.

Understanding Rounding to Even

But what does it mean to round a number to even? According to Wikipedia, the process changes under specific conditions. For instance, consider this example from unit tests:

assert_equal(

767573.18759,

767573.1875850001.round(5, half: :even)

)

This code suggests that rounding 767573.1875850001 to the nearest even number at the fifth decimal place results in 767573.18759. However, it raises an interesting question: why would a function that rounds to even yield an odd digit at the end?

After two days of seeking clarification from the Ruby mailing list, I still had no answers.

Clarification on Rounding Rules

Through research, I uncovered that "rounding half to even" pertains specifically to how you handle halves. For instance, rounding 1.5 requires knowing which direction to go—towards the nearest even number, which is 2. Conversely, 1.6 rounds to 2, while 1.4 rounds to 1.

Rounding 767573.1875850001 is puzzling since it is very close to 767573.187585. However, because it does not represent a precise half, the rounding rule applies differently: you round to the nearest whole number, which in this case is 767573.18759. The fact that it's so close to the half doesn't influence the outcome.

This unit test could be misleading, but it certainly encouraged me to reassess my understanding of rounding. At least I've gained a fun fact to share with friends!

Stay tuned for a follow-up article where I will analyze the code modifications in more detail. Don't forget to subscribe for more insights into programming!

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Manifesting Dreams: The Journey of Aspirations Realized

Explore how the author's dreams evolved into reality through various experiences, highlighting the power of thoughts.

# Discovering Your True Self: A Journey to Self-Improvement

Explore self-discovery techniques like meditation, journaling, and trying new activities to connect with your true self.

Understanding Fat Gain: Causes, Consequences, and Solutions

Explore the intricacies of fat gain, including its causes and how to effectively prevent and reverse it through lifestyle changes.

Embrace Your Uniqueness: The Snowflake's Message

Discover the profound lessons snowflakes teach us about individuality and embracing our uniqueness in a beautiful world.

Empowering Life Lessons: Turning Struggles into Strengths

Discover how tough experiences can lead to personal growth and the insights gained from overcoming challenges.

Unlocking Micro SaaS Success: Harnessing Soft Skills for Growth

Discover how to leverage soft skills for building a successful Micro SaaS business.

A Unique Fusion of Art, Science, and Sustainability in Puerto Rico

Discover the intersection of art, science, and sustainability in the Puerto Rican rainforest through a personal journey of exploration and resilience.

Mastering Automated Trading Bots: Integrating with Crypto APIs

Explore how to seamlessly connect trading bots with cryptocurrency exchanges using API communication techniques.