Seq

В ходе беседы возникли пару маленьких, но интересных вопросов. =)

На свежую голову написал.

Автомагическое обнаружение overflow для рекурсий

Q: можно ли обнаружить максимальное число в произвольном ряде, для примера Xn * Xn-1 * … X0 eщe не вызвающее overflow для целого при рекусивных вычислениях.

A: Можно. Запас можно проверить делением. Но есть противоречие. Для обнаружения необходимо войти в рекурсию с заведомо большим числом рекурсивных итераций. Что порождает доп вычисления, плюс может быть чревато последствиями
Что делает метод ограниченно применимым, пожалуй только для предварительных оценок.

seq.go
/*
 *
 * Copyright 2022 Oleg Borodin  <borodin@unix7.org>
 *
 */
 
package main
 
import (
    "fmt"
    "math"
)
 
const maxUint uint = math.MaxUint64
 
func seq1(next uint) uint {
    if (next == 0) {
        return 0
    }
    if (next == 1) {
        return 1
    }
    return next * seq1(next - 1)
}
 
func seq2(next uint, max uint) uint {
    if (max == 0) {
        return 0
    }
    if (max == 1) {
        return 1
    }
    if (next >= max) {
        return next
    }
    res := seq2(next + 1, max)
    fmt.Printf("### step = %2d div = %21d <> next = %2d res = %21d max = %21d\n",
                    max - next, maxUint / res, next, res, maxUint - res)
    return next * res
}
 
 
func main() {
    var num uint = 25
    res1 := seq1(num)
    fmt.Println(num, res1)
 
    res2 := seq2(1, num)
    fmt.Println(num, res2)
}

Граница для числа итераций = 17 (step 16), для большего числа overflow.

Банки

Реплика была шуткой наполовину. В банках действительно используют целые числа. Но один момент - взымание-исчисление процентов.

Берется дробное от целого. 30% от 100 центов = 33.33333333333333333333.
Итого все банки порождают очень маленький шум погрешности от вычислений (“шумы квантования” =) ), иногда трактуемый в пользу банка, иногда клиента. Похожий на тот, который возникает при операциях с мантиссой float.