消費税0%と1%は何が違う?「数字を変えるだけ」で済まないソフトウェア設計の話

目次

はじめに

最近、

  • 「消費税を0%にするべき」
  • 「いや、1%は残すべき」

という議論をよく見かけます。

一見すると、

  • 0%
  • 1%

は「たった1%の違い」に見えます。

そのため、

初心者さん

システム改修が大変って言うけど、数字を変えるだけでは?

初心者さん

なぜ消費税0%はシステム改修が大変なのか?

と思う人も多いかもしれません。

実際、ニュース番組などでも、

初心者さん

0.00001%ならいいの?

初心者さん

0%じゃなければ大丈夫?

という話をしている場面を見かけます。

しかし、ソフトウェア開発の世界では、「0」と「0ではない」
の間には、大きな違いがあることがあります。

しかも怖いのは、「0を特別扱いしていた」
ケースだけではありません。

むしろ現実では、「0が来ることを想定していなかった」
ことで事故が起きることの方が多いのです。

今回は、

  • なぜ0が特別なのか
  • なぜ「数字を変えるだけ」で済まないのか
  • なぜ仕様変更が大変なのか
  • 変更しやすい設計とは何か

を、ソフトウェア設計・組み込み開発の視点から分かりやすく解説します。


「0」と「0ではない」は別物になることがある

初心者さん

消費税0%って、数字を変えるだけじゃないんですか?

エンジニアくん

そう見えるよね。でもソフトウェアでは“0”が特別扱いされることがあるんだ

初心者さん

1%との違いって、たった1%ですよね?

エンジニアくん

人間から見るとそうなんだけど、プログラムでは“0か、それ以外か”で意味が変わることがあるんだよ


報道では、

  • 消費税0% → 約1年
  • 消費税1% → 約半年

という改修期間の差も話題になっています。

これは、「0%と1%でシステムへの影響が違う」
可能性があるためです。

例えば、人間なら、

  • 0%
  • 0.00001%
  • 1%

は「ほぼ同じ」に感じるかもしれません。

しかしソフトウェアでは、

  • 0
  • 非0

で処理が分かれることがあります。

例えば:

C
if (tax_rate == 0) {
    // 非課税
} else {
    // 通常の税計算
}

この場合、

  • 1%
  • 5%
  • 10%

は同じ「通常処理」です。

しかし、0だけは別扱いになります。

つまり、「0%は税率が低い」のではなく、
「税が存在しない」として扱われる可能性があるのです。

プログラミングの分岐処理についてはこちらの記事で解説しています。


ただし、本当に怖いのは「0を想定していない」ケース

しかし、現実のシステムで本当に怖いのは、「最初から0を特別扱いしていた」
ケースだけではありません。

むしろ、「0が来ることを想定していなかった」
ことで事故が起きる方が多いです。


0で割るとどうなる?

例えば、「1000円を5人で割る」
なら、1人200円です。

では、「1000円を0人で割る」
はどうでしょうか。

「誰もいないのに、1人あたりいくら?」

という意味不明な計算になります。

数学でも、0で割ることはできません。

コンピュータでも同じです。


例えば、こんなコード。

C
price_per_person = total_price / people_count;

これは、「合計金額を人数で割る」という意味です。

しかし、

C
people_count = 0

のとき、

1000 / 0

のような計算になってしまいます。

その結果、

  • エラー
  • 異常終了
  • 例外
  • 想定外動作

などが発生することがあります。

ここで重要なのは、「0を特別扱いしていた」のではなく、

「0が来ることを想定していなかった」ことです。


消費税0%も「単純な掛け算」だけなら壊れないかもしれない

ここで、

初心者さん

でも税率って掛け算だから、0でも問題なくない?

と思う人もいるかもしれません。

実際、それはかなり鋭い視点です。

例えば:

C
tax = price * tax_rate;

なら、

C
tax_rate = 0

でも、

price * 0 = 0

になるだけです。

つまり、「0%だから必ずシステムが壊れる」

わけではありません。

これはかなり重要です。


では、なぜ改修が大変になるのか

問題は、「税率の数字」

だけではないからです。

実際のシステムでは、

  • 非課税扱い
  • 帳票表示
  • 税区分
  • レジ表示
  • 会計システム
  • 外部システム連携
  • 過去データ
  • 軽減税率
  • 例外処理

など、さまざまな要素が絡みます。

つまり、「税率0%」が、
「税そのものが存在しない状態」として扱われる可能性があるのです。


では、1%なら簡単なのか?

実際、報道では、

  • 消費税0% → 約1年
  • 消費税1% → 半年程度

の改修期間が必要という話もあります。

これを見ると、

初心者さん

やっぱり0%だけ特別なのでは?

と思うかもしれません。

実際、システムによっては、

  • 0%
  • 非0%

で処理が分かれていることがあります。

そのため、「1%なら既存システムを流用しやすい」
ケースもあり得ます。


ただし、ここで重要なのは、「1%なら簡単」
というわけでもないことです。

現実の大規模システムでは、

  • 外部連携
  • 過去互換
  • 長年の継ぎ足し
  • 特殊仕様

などが積み重なっています。

そのため、「本来は簡単な変更」でも、大規模改修になることがあります。


「数字を変えるだけ」で済まない理由

初心者さん

でも、税率変更って数字を変えるだけじゃないんですか?

エンジニアくん

小さいプログラムならそういうこともある。でも大規模システムは影響範囲が広いんだ

初心者さん

影響範囲?

エンジニアくん

変更がどこまで波及するか、ってことだね


例えば消費税変更では、

  • レジ
  • 会計システム
  • 帳票
  • API
  • データベース
  • ECサイト
  • 在庫管理
  • 外部連携
  • テスト
  • 過去互換

など、多くの場所に影響します。

しかも大規模システムほど、

  • 長年の継ぎ足し
  • 古い仕様
  • 特殊対応
  • 過去互換

が積み重なっています。

そのため、「数字を1個変えるだけ」
のつもりでも、大規模改修になることがあります。


エンジニアが仕様変更を怖がる理由

ここは誤解されやすい部分です。

エンジニアが仕様変更に慎重になると、「変更したくないだけでは?」
と思われることがあります。

しかし実際は、「どこに影響するか分からない」
ことを怖がっているケースが多いです。

例えば、

  • この変更で別機能が壊れないか
  • 古いデータに影響しないか
  • 特殊条件に当たらないか
  • 外部システムと整合するか

などを確認する必要があります。

特に大規模システムでは、「修正そのもの」より、
「影響調査とテスト」の方が大変になることも珍しくありません。


「0.00001%なら簡単」は本当?

ここで、

初心者さん

じゃあ0.00001%ならいいのでは?

という疑問も出てきます。

実際、ソフトウェアによっては、

  • 0%
  • 非0%

で分岐しているだけなら、

0.00001%は通常処理として扱える可能性があります。

つまり、「0だけが特殊」な設計もあるのです。


ただし、小数には別の難しさがある

しかし、小数には別の問題があります。

コンピュータでは、少数表現には誤差があり、

0.1 + 0.2 = 0.3

が成り立たないことが前提であることが多いです。

これは、「浮動小数点誤差」という有名な問題です。

つまり、「0に近ければ簡単」とも限りません。

ソフトウェアでは、

  • 0
  • 小数
  • 丸め
  • 誤差

など、それぞれ別の難しさがあります。

浮動小数点についてはこちらの記事で解説しています。


では、変更しやすい設計とは?

ここがこの記事で一番重要な部分です。

ただし、

初心者さん

将来変更されるかもしれないから全部柔軟にしよう

ではありません。

それをやりすぎると、

  • 過剰設計
  • 複雑化
  • 可読性低下

につながります。

重要なのは、

エンジニアくん

変わりそうな部分の影響範囲を小さくする

ことです。


悪い例:変更箇所が散らばる

例えば:

C
total = price + price * 0.10;

こういうコードが大量に散らばると、

税率変更時に全体修正が必要になります。


少し改善した例

C
#define TAX_RATE 0.10

total = price + price * TAX_RATE;

これだけでも、

  • 修正箇所集約
  • 影響範囲縮小

ができます。


さらに変更しやすい設計

C
int calculate_tax_included_price(int price, double tax_rate) {
    return price + (int)(price * tax_rate);
}

こうすると、

  • 税率変更
  • 軽減税率
  • 計算ルール変更

などの影響を閉じ込めやすくなります。

影響範囲を小さくする設計についてはこちらの記事で解説しています。


ただし「何でも抽象化」は危険

初心者さん

じゃあ、将来変更に備えて全部分ければいいんですか?

エンジニアくん

それも違うんだ

初心者さん

違う?

エンジニアくん

柔軟性を増やしすぎると、逆に複雑になって保守しにくくなるんだよ


変更容易性を意識しすぎると、

  • abstraction地獄
  • 設定地獄
  • 汎用化しすぎ

になり、逆に保守性が下がることがあります。

つまり、「未来を全部予測して設計する」
のは現実的ではありません。

今回の消費税0%も予測するのは難しかったと思います。

重要なのは、

  • 今の要求にはシンプルに作る
  • ただし変わりそうな部分は分離する
  • 影響範囲を閉じ込める

ことです。


組み込み開発でも同じことが起きる

これは組み込み開発でも非常によくあります。

例えば:

C
if (sensor_value == 0) {
    // センサ異常
}

という仕様だった場合、

後から、「0も正常値として扱いたい」
となると、システム全体に影響することがあります。

つまり、「0 = 異常」という前提が、システム全体に広がっているのです。


まとめ

ソフトウェアの世界では、

  • 0
  • NULL
  • false

などが特別な意味を持つことがあります。

しかも怖いのは、「0を特別扱いしている」ケースだけではありません。

むしろ、「0が来ることを想定していない」
ことで事故が起きることも非常に多いです。

また、仕様変更が大変なのは、

  • エンジニアが変更を嫌がっている
  • 数字変更だけで済む

からではなく、

  • 影響範囲
  • 過去互換
  • 巨大システム
  • 長年積み重なった設計

が関係しているためです。

だからこそソフトウェア設計では、「変更しやすさ」が重要になります。

ただし、「何でも柔軟にする」のではなく、
「必要な部分だけ影響範囲を閉じ込める」ことが、本当に大切なのです。

この記事が参考になった方へ

今回扱ったようなソフトウェア設計の考え方はこちらの記事で整理しています。

今回扱ったプログラムの前提となるC言語の基本文法はこちらの記事で整理しています。

エンジニアとして技術を学ぶことは重要ですが、
キャリアや副業についても同時に考える必要があります。

副業の現実や市場価値、今後のキャリア戦略については、
こちらの記事でまとめています。

技術に関するご相談・開発・自動化ツール作成・記事執筆などのご依頼も承っています。

小さなご相談からでもお気軽にご連絡ください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

組み込みソフトエンジニアとして働きながら、
C言語・メモリ・ポインタなどの基礎から実務まで解説しています。

副業・キャリアについても実体験ベースで発信中です。

X・Qiita・noteでも発信しています。
X:更新情報・日常
Qiita:技術発信
note:キャリア・副業

▼まずはここから読むのがおすすめ
C言語文法シリーズ
メモリ領域解説シリーズ
割り込み処理解説シリーズ
ソフトウェア設計解説シリーズ
キャリアと副業ロードマップ

コメント

コメントする


目次