jenner/LstGen

Rounding in go code

polderudo opened this issue · 2 comments

Hello Igor,
first of all, thanks for this library. It saves a lot of time...
We are having a problem with the go implementation. I'm pertty sure it's related to the roundings (see the FIXIT code parts), thus the missing ROUND_DOWN in the github.com/shopspring/decimal lib.
E.G. the calculation like:
https://www.bmf-steuerrechner.de/interface/2021Version1.xhtml?code=eP2021&PVZ=1&R=1&RE4=207753&LZZ=2&STKL=1&AF=0&AJAHR=0&ALTER1=0&ENTSCH=0&F=0&JFREIB=0&JHINZU=0&JRE4=0&JVBEZ=0&KRV=0&KVZ=0.9&LZZFREIB=0&LZZHINZU=0&PKPV=0&PKV=0&PVS=0&SONSTB=0&STERBE=0&VBEZ=0&VBEZM=0&VBEZS=0&VBS=0&VJAHR=0&VKAPA=0&VMT=0&ZKF=0&ZMVB=0&JRE4ENT=0&SONSTENT=0

returns a drifference of 22 cents compared to the www.bmf-steuerrechner.de output.

For now we overcome this by using the javascript output and running it in a v8 engine inside our app, with this BigDecimal class:
`
// http://mikemcl.github.io/big.js/#toN
let BigDecimal = class extends Number {
static ROUND_DOWN = 0
static ROUND_UP = 3

constructor(value) {
    super(value)
}

static valueOf(value){
    return new BigDecimal(value)
}

divide(other, scale, rounding){
    if(scale==undefined || rounding==undefined){
        return new BigDecimal(this/other)
    }
    return new BigDecimal(this / other).setScale(scale, rounding)
}

multiply(other){
    return new BigDecimal(this*other)
}


setScale(scale, rounding){
    let b = Big(this)
    return new BigDecimal(b.round(scale, rounding).toNumber())
}

add(other){
    return new BigDecimal(this+other)
}

subtract(other){
    return new BigDecimal(this-other)
}

longValue(){
    return this.abs().toNumber();
}

compareTo(other){
    if(this>other){
        return new BigDecimal(1)
    }else if (this<other){
        return new BigDecimal(-1)
    }else{
        return new BigDecimal(0)
    }
}


static ZERO() {
    return new BigDecimal(0);
}
static ONE() {
    return new BigDecimal(1);
}
static TEN() {
    return new BigDecimal(10);
}

}
`

This works ok, but requires e.g. "rogchap.com/v8go" which uses cgo, which i would like to avoid.

Is there any chance to get this rounding thing fixed, so we can use the pure go implementation?
I belive, that using something like the BigDecimal class in go as an abstraction should work. As far as i can see, we don't need that complicated function, just add/mul/div/sub and round and those 2 rounding functions should be easily implementable in go:
up: math.Ceil(value10^scale)/10^scale
down: math.Floor(value
10^scale)/10^scale
right?

And one more question. Are you going to add the 2022 calculation also? The BFM allready released a pre version:
(https://www.bundesfinanzministerium.de/Content/DE/Downloads/Steuern/Steuerarten/Lohnsteuer/Programmablaufplan/2021-10-05-PAP-2022-entwuerfe.html)

Thank you

Hi Udo,

Is there any chance to get this rounding thing fixed, so we can use the pure go implementation?

the Go implementation was provided by a contributor in 1a80b68, unfortunately I have no experience with Go, so I cannot fix the problem myself, so if you could provide a fix and submit a PR I'd be happy to merge it into the code base, so you don't have to workaround the issue.

And one more question. Are you going to add the 2022 calculation also?

I'd rather wait until BMF releases a final version. If you'd like to try it out before they do just add the config for 2022 in https://github.com/jenner/LstGen/blob/master/lstgen/pap.py#L88

Regards
Igor

The current 2022 calculations are now in and the rounding is working. I tested through the BFM API