How to resolve the algorithm Pathological floating point problems step by step in the Crystal programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Pathological floating point problems step by step in the Crystal programming language

Table of Contents

Problem Statement

Most programmers are familiar with the inexactness of floating point calculations in a binary processor. The classic example being: In many situations the amount of error in such calculations is very small and can be overlooked or eliminated with rounding. There are pathological problems however, where seemingly simple, straight-forward calculations are extremely sensitive to even tiny amounts of imprecision. This task's purpose is to show how your language deals with such classes of problems.

A sequence that seems to converge to a wrong limit. Consider the sequence:

As   n   grows larger, the series should converge to   6   but small amounts of error will cause it to approach   100.

Display the values of the sequence where   n =   3, 4, 5, 6, 7, 8, 20, 30, 50 & 100   to at least 16 decimal places.

The Chaotic Bank Society   is offering a new investment account to their customers. You first deposit   $e - 1   where   e   is   2.7182818...   the base of natural logarithms. After each year, your account balance will be multiplied by the number of years that have passed, and $1 in service charges will be removed. So ...

What will your balance be after   25   years?

Siegfried Rump's example.   Consider the following function, designed by Siegfried Rump in 1988.

Demonstrate how to solve at least one of the first two problems, or both, and the third if you're feeling particularly jaunty.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Pathological floating point problems step by step in the Crystal programming language

Source code in the crystal programming language

require "big"

ar = [0.to_big_d, 2.to_big_d, -4.to_big_d]

100.times { ar << 111 - 1130.to_big_d.div(ar[-1], 132) + 3000.to_big_d.div((ar[-1] * ar[-2]), 132) }

[3, 4, 5, 6, 7, 8, 20, 30, 50, 100].each do |n|
  puts "%3d -> %0.16f" % [n, ar[n]]
end


require "big"

ar = [0, 2, -4].map(&.to_big_r)

100.times { ar << (111 - 1130.to_big_r / ar[-1] + 3000.to_big_r / (ar[-1] * ar[-2])) }

[3, 4, 5, 6, 7, 8, 20, 30, 50, 100].each do |n|
  puts "%3d -> %0.16f" % [n, ar[n]]
end


require "big"

def e(precision)
  y = BigDecimal.new(10.to_big_i ** precision, precision)
  d = y
  i = 1

  while true
    d = (d / i).scale_to(y)
    y2 = y + d
    return y if y2 == y
    y = y2
    i += 1
  end
end

balance = e(50) - 1
1.upto(25) { |y| balance = (balance * y) - 1 }
puts "Bank balance after 25 years = #{balance.to_f}"


require "big"
   
e = 106246577894593683.to_big_d.div(39085931702241241.to_big_d)

balance = e - 1
1.upto(25) { |y| balance = (balance * y) - 1 }
puts "Bank balance after 25 years = #{balance.to_f}"


require "big"

def rump(a, b)
  a, b = a.to_big_r, b.to_big_r
  333.75.to_big_r * b**6 + a**2 * (11 * a**2 * b**2 - b**6 - 121 * b**4 - 2) + 5.5.to_big_r * b**8 + a / (2 * b)
end
 
puts "rump(77617, 33096) = #{rump(77617, 33096).to_f}"


  

You may also check:How to resolve the algorithm Enumerations step by step in the BASIC programming language
You may also check:How to resolve the algorithm Doubly-linked list/Traversal step by step in the Haskell programming language
You may also check:How to resolve the algorithm Sparkline in unicode step by step in the Raku programming language
You may also check:How to resolve the algorithm Ranking methods step by step in the Cowgol programming language
You may also check:How to resolve the algorithm Operator precedence step by step in the PicoLisp programming language