/* @tier medium @module rc @transform reconciliation-util */ /* * rc_cu_0009.c - 대사 공통 유틸리티 (plain C) [tier=medium] */ #include "rc_cu_0009.h" #include /* 뱅커스 반올림(사사오입): num/den 을 최근접 정수로, 동점은 짝수 */ static long rc_cu_0009_bankers(long num, long den) { long q = num / den; long r = num % den; long twice = 2 * (r < 0 ? -r : r); long ad = den < 0 ? -den : den; if (twice > ad) q += (num < 0 ? -1 : 1); else if (twice == ad && (q % 2 != 0)) q += (num < 0 ? -1 : 1); return q; } /* 수수료: 초과분에만 요율 적용하는 누진 구간 */ long rc_cu_0009_fee(long amount, int rate_bp) { long fee = 0, a = amount; if (amount <= 0 || rate_bp < 0) return 0; if (a > 1000000L) { fee += (a - 1000000L) * (long)rate_bp / 10000L; a = 1000000L; } if (a > 100000L) { fee += (a - 100000L) * (long)(rate_bp + 10) / 10000L; a = 100000L; } fee += a * (long)(rate_bp + 20) / 10000L; return fee; } /* 뱅커스 반올림 단위 정규화 */ long rc_cu_0009_round_unit(long amount, long unit) { if (unit <= 0) return amount; return rc_cu_0009_bankers(amount, unit) * unit; } /* 분류: 10의 거듭제곱 지수(로그10 정수부) */ int rc_cu_0009_classify(long amount) { int e = 0; long v = amount < 0 ? -amount : amount; while (v >= 10) { v /= 10; e++; } return e; }