# NAN(Not a Number)の秘めたる生活

NAN(Not a Number)は、コンピュータシステムにおいて数値演算の結果が未定義であるか、表現不可能であることを示す特別な浮動小数点数です。名前には「単なる『数ではない』もの」という印象を与えるかもしれませんが、実際には Python や JavaScript、C++ といったプログラミング言語における数学的な整合性を維持する上で、極めて重要な役割を果たしています。

## NAN とは何か?

NAN は **Not a Number**(数ではない)の略称であり、浮動小数点算術のための IEEE 754 標準において導入されました。他の数値とは異なり、NAN は以下のような独特の性質を備えています:

- `NaN == NaN` は常に `False` です(自身と等しいことはありません)。
- NAN を含むあらゆる比較演算の結果は `False` となります。
- 明示的に処理されない限り、計算結果に伝播します。

### NAN が生じる主な原因

| 操作 | 例 | 結果 |
|------|-----|------|
| ゼロでの除法(場合による) | `0 / 0` | NAN |
| 負数の平方根 | `sqrt(-1)` | NAN |
| 非正数の対数 | `log(-5)` | NAN |
| 無効な型変換 | `"abc" * 2`(一部の言語) | NAN |

## コード内での NAN の処理方法

### Python の例

```python
import math

# NAN の作成
result = 0 / 0  # nan が返される
print(result)   # 出力: nan

# NAN の検出
if math.isnan(result):
    print("これは有効な数値ではありません")

# try-except やチェックを用いた安全な計算処理
def safe_divide(a, b):
    if b == 0:
        return None  # または必要に応じて別の方法で対応
    return a / b
```

### JavaScript の例

```javascript
const result = NaN;
console.log(typeof result); // "number"

if (Number.isNaN(result)) {
    console.log("結果は数値ではありません");
}

// 安全な除法関数
function safeDivide(a, b) {
    if (b === 0) return null;
    return a / b;
}
```

## なぜ NAN が存在するのか?

NAN は、以下の区別を明確にするために存在します:
1. **エラー**(例:ゼロでの除法)
2. **未定義の結果**(例:`0/0`)
3. **表現不可能な値**(例:実数系における `sqrt(-1)`)

この区別により、プログラムは問題のある計算を後で確認できるようにしながらも、健全に動作し続けることができます。

## 推奨されるベストプラクティス

- 演算を実行する前に、必ず入力値を検証してください。
- `x == NaN` ではなく、`math.isnan()`(Python)または `Number.isNaN()`(JavaScript)などのライブラリ関数を使用してください。
- データパイプラインの早期段階で NAN を処理し、沈黙型の失敗を未然に防ぎましょう。
- 文脈に応じて、NAN を意味のあるデフォルト値(例:0、null、特定のフラグ)に置き換えることも検討してください。

---

NAN の秘めたる生活を理解することは、あらゆるプログラミング環境において、より堅牢で予測可能な数値コードを記述するための開発者の助けとなります。

2026/04/26 19:56

# NAN(Not a Number)の秘めたる生活 NAN(Not a Number)は、コンピュータシステムにおいて数値演算の結果が未定義であるか、表現不可能であることを示す特別な浮動小数点数です。名前には「単なる『数ではない』もの」という印象を与えるかもしれませんが、実際には Python や JavaScript、C++ といったプログラミング言語における数学的な整合性を維持する上で、極めて重要な役割を果たしています。 ## NAN とは何か? NAN は **Not a Number**(数ではない)の略称であり、浮動小数点算術のための IEEE 754 標準において導入されました。他の数値とは異なり、NAN は以下のような独特の性質を備えています: - `NaN == NaN` は常に `False` です(自身と等しいことはありません)。 - NAN を含むあらゆる比較演算の結果は `False` となります。 - 明示的に処理されない限り、計算結果に伝播します。 ### NAN が生じる主な原因 | 操作 | 例 | 結果 | |------|-----|------| | ゼロでの除法(場合による) | `0 / 0` | NAN | | 負数の平方根 | `sqrt(-1)` | NAN | | 非正数の対数 | `log(-5)` | NAN | | 無効な型変換 | `"abc" * 2`(一部の言語) | NAN | ## コード内での NAN の処理方法 ### Python の例 ```python import math # NAN の作成 result = 0 / 0 # nan が返される print(result) # 出力: nan # NAN の検出 if math.isnan(result): print("これは有効な数値ではありません") # try-except やチェックを用いた安全な計算処理 def safe_divide(a, b): if b == 0: return None # または必要に応じて別の方法で対応 return a / b ``` ### JavaScript の例 ```javascript const result = NaN; console.log(typeof result); // "number" if (Number.isNaN(result)) { console.log("結果は数値ではありません"); } // 安全な除法関数 function safeDivide(a, b) { if (b === 0) return null; return a / b; } ``` ## なぜ NAN が存在するのか? NAN は、以下の区別を明確にするために存在します: 1. **エラー**(例:ゼロでの除法) 2. **未定義の結果**(例:`0/0`) 3. **表現不可能な値**(例:実数系における `sqrt(-1)`) この区別により、プログラムは問題のある計算を後で確認できるようにしながらも、健全に動作し続けることができます。 ## 推奨されるベストプラクティス - 演算を実行する前に、必ず入力値を検証してください。 - `x == NaN` ではなく、`math.isnan()`(Python)または `Number.isNaN()`(JavaScript)などのライブラリ関数を使用してください。 - データパイプラインの早期段階で NAN を処理し、沈黙型の失敗を未然に防ぎましょう。 - 文脈に応じて、NAN を意味のあるデフォルト値(例:0、null、特定のフラグ)に置き換えることも検討してください。 --- NAN の秘めたる生活を理解することは、あらゆるプログラミング環境において、より堅牢で予測可能な数値コードを記述するための開発者の助けとなります。

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

現代の JavaScript エンジン(例:Safari の JavaScriptCore(JSC))は、メモリ使用量とパフォーマンスを最適化する技術として「NaN boxing」と呼ばれる手法を採用しています。この手法では、IEEE 754 標準に基づき、符号ビット、指数部、そして診断情報やタイプタグのための 51 ビットのペイロードを含む 52 ビットのマンティッサを持つ二重精度浮動小数点数形式を再利用し、IEEE 754 の NaN(数値なし)の未使用ビット内で、すべてのデータ型——数字、オブジェクト、ブール値、null、undefined——を格納します。そのためには、有効な数値範囲に対してオフセット $2^{48}$(0x1000000000000ll)を追加し、低位のビットをポインタの格納および ECMAScript のリテラル用として特別に割り当てたビットパターンを確保します。具体的には、False(0x06)、True(0x07)、Undefined(0x0a)、Null(0x02)、ValueEmpty(0x00)、ValueDeleted(0x04)といった値が対応します。この手法は効率性を著しく向上させた一方、厳格な検証プロトコルが適用される前には、これらの特別に設計された NaN ペイロードを操作することで CVE-2010-1807 といった脆弱性を引き起こすという歴史的なセキュリティリスクをもたらしました。動的型付け言語において計算速度とシステムセキュリティのバランスを取るためには、quiet NaN(qNaN)と signaling NaN(sNaN)の役割を理解することが不可欠です。

本文

IEEE 浮動小数点規格は、数値ではない値を表現するために用いられる特殊な値「Not-a-Number(NaN)」を定義しています。倍精度の NaN では、自由に用途が決められるペイロードとして 51 ビットの空間が用意されており、特に動的型付け言語において実行時における全ての非浮動小数点値とその型をこのペイロードに格納するという、非常に面白い応用例があります。

%%%%%% 更新(2019 年 4 月) %%%%

私が !!con West 2019 で開催した「NaN の秘めたる生活」に関するライトニングトークの内容です。今回は詳細は簡略化されていますが、より多くのジョークを盛り込んでいます。録画映像はこちらからご覧いただけます。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

私がここで言う「NaN」と「浮動小数点」とは、主に 1985 年に(多くの変遷を伴って)誕生した汎用性の高い IEEE 754-2008 規格で定義された表現方法を指します。この規格は、異なるプロセッサが使っていた多様な不整合な浮動小数点表現によって引き起こされる「無法状態」を鎮め、コードの移植性を確保するための標準的な表現手法としての必要性から生まれました。

浮動小数点値は実数に対する離散的で対数的な近似であり、以下に示す 3 ビットの指数部、3 ビットの有効数字(仮数のこと)を持つ玩具的な浮動小数点表現により定義される点を可視化した図です(画像出典:論文「区間の中央値をどのように計算するのか?」より。この論文は中央値の計算でよく現れる算術的な偽像について指摘しています)。

私がここで論じる NaN は IEEE 754-2008 の外には存在しないため、以下では規格を簡単に解説します。

IEEE 754-2008 の極めて簡潔な概要

この規格は、基底 2 および基底 10 を用いた対数的近似値の分布を定義しています。基底 2 にては、16 ビットから 256 ビットまでの 2 のべき乗幅のすべての表現を定義し(正確にはそうではありません。詳細な規格については仕様書の 13 ページを参照)、基底 10 では 32 ビットから 128 ビットまでの 2 のべき乗幅の表現を定義しています。これらが唯一の標準化されたビット幅です。つまり、プロセッサが 32 ビットの浮動小数点値をサポートしている場合、その実装が規格準拠の表現で行われている可能性は極めて高いと言えます。

さて、規格に準拠した表現を見てみましょう。まずは基底 2 の 16 ビット幅である「binary16」フォーマットです:

1 符号ビット | 5 指数ビット | 10 有効数字ビット S E E E E E M M M M M M M M M M

これらのビットが数値を表現する方法については別の機会に譲りますが、説明を求める場合はこちらのわかりやすい解説記事もおすすめです。

簡潔に触れると、例えば以下のように様々な値をこれら 16 ビットで符号化できます。要点は、この 16 ビットを使って多様な値を表現できることです。

0 01111 0000000000 = 1 0 00000 0000000000 = +0 1 00000 0000000000 = -0 1 01101 0101010101 = -0.333251953125

以上のように、私たちは有限で離散的な実数の集合を表現することができるようになります。数値表現としてこれが望ましい状況です。

さらに興味深くは、規格はまた特殊な値である「±無限大」と、「静かな(quiet)」ならびに「シグナリングする(signaling)」NaN を定義しています。「±無限大」は自明なオーバーフロー挙動を示します:上記の可視化では ±15 が正確に表現可能な最大の絶対値であり、それ以上の絶対値を持つ値との計算によってオーバーフローが生じると、±無限大へと遷移します。規格書には、異なる丸めモードに基づいて操作の結果として±無限大を返すべきかどうかの指針が記されています。

IEEE 754-2008 が NaN について述べていること

まず NaN がどのように表現されるか見てから、「静かな」と「シグナリングする」の違いを整理しましょう。

規格には以下のように記載されています(仕様書 p.35, §6.2.1):

すべてのバイナリ形式の NaN ビット列では、偏った指数部 E のすべてのビットが 1 に設定されている (参照 3.4)。静かな NaN のビット列は、桁落ち仮数字段 T の最初のビット(d1)を 1 にすることで符号化されるべきである。シグナリングする NaN のビット列は、桁落ち仮数字段の最初のビットを 0 にすることで符号化されるべきである。

例えば、binary16 フォーマットにおいて、NaN は以下のビットパターンで指定されます:

s 11111 1xxxxxxxxxx = 静かな (qNaN) s 11111 0xxxxxxxxxx = シグナリングする (sNaN) **

これは非常に多くのビットパターンの集合です。符号ビットを無視しても、桁落ち仮数字段の位数から減じた数のビット分(2 のべき回)のパターンが存在し、これらすべてのパターンは NaN を表現しています。私たちはこれらの残りビットを「ペイロード」と呼びましょう。注釈:sNaN の場合、少なくとも桁落ち仮数字段の 1 ビットは 1 に設定する必要があり、全ゼロのペイロードを持つことはできません。なぜなら、指数部が全 1 で仮数部分が全 0 のビットパターンは無限大を表現するからであり、その状態にありえないためです。

私には、NaN がシグナリングするか否かを表すフラグとして仮数字段の上位ビットが使われていることが奇妙に思えます。おそらく浮動小数点パイプラインの実装方法に関連して、符号ビットを使って例外の有無を判定するのが不自然だからではないでしょうか。

現代のコムモディティ(汎用)ハードウェアではよく 64 ビットの浮動小数点(倍精度)が使われており、倍精度フォーマットでは仮数字段が 52 ビットあるため、ペイロードとして利用可能なビットは 51 ビットとなります。

さて、ここで「静かな」と「シグナリングする」NaN の違いを見てみましょう(仕様書 p.34, §6.2):

シグナリングする NaN は、初期化されていない変数や標準の範囲を超える算術的な拡張表現(例えば複素線形無限大や極めて広い範囲など)、といったこの規格の範囲外にあるものを表現することを可能にします。一方、静かな NaN は、実行者の裁量によって、無効なデータまたは利用できないデータから引き継がれた診断情報および結果を後から検証するための情報を提供すべきです。NaN に含まれる診断情報の伝播を促進するため、可能な限り多くの情報を NaN の演算結果に保持するべきです。

通常の例外処理下では、無効な操作(invalid operation)例外を発し、かつ浮動小数点の結果が返されなければならないようなすべての操作は、静かな NaN を返すものとする。

つまり、「シグナリングする」NaN は例外を発生させることがあり、規格自体が浮動小数点がハードウェアかソフトウェアで実装されているかを無視しており、具体的にどのような例外かが明確にはされていません。ハードウェアの場合、これは浮動小数点ユニット(FPU)が例外フラグを設定することに対応し、C の標準では浮動小数点の計算例外を表すために SIGFPE シグナルを定義・要求しています。

この最後の引用文は、「シグナリングする」NaN を受ける操作が警報を発した上で、その NaN を静かにして伝播させることを示唆しています。なぜそのような状況が生じるのでしょうか?それは最初の引用文で説明されています:初期化されていない変数を「シグナリングする」NaN で表現することで、もし誰かがその値を操作しようとした場合(最初に初期化する前に)、それが意図した行動ではなかった可能性が高いことを告げることが可能となるのです。

逆に、「静かな」NaN は一般的な NaN です。qNaN(quiet NaN)は、真に数ではない結果が得られる際に生成されます(例えば負の数の平方根を取ろうとした場合など)。ここで特に注意すべきなのは以下の一文です:

NaN に含まれる診断情報の伝播を促進するため、可能な限り多くの情報を NaN の演算結果に保持するべきです。

つまり、IEEE 浮動小数点規格による公式な推奨は、ある qNaN をその状態のまま変更せずにそのまま使用し、上記で見たようなペイロードを使って「診断情報」を伝播させることに使うという方向性です。「これは NaN に追加情報を無理やり詰め込むための手招きでしょうか?」という問いに対し、答えは YES です!

ペイロードをどう活用できるのか?

私が本当に興味を持っているのはこの点、あるいはさらに具体的に言えば、「人々はペイロードをどのように利用しているのか」という問いです。

この質問に対する最も満足できる回答は、動的型付け言語においてデータを型情報とともに伝播させるために、NaN のペイロードを利用しているという事実でした。具体的な実装例としては Lua や JavaScript などが挙げられます。なぜ動的型付け言語なのか?それは、変数の型が実行時に変化するため、型の情報を必ずとも伝えなければならないからです。ここで NaN のペイロードは、その型情報に加えて実際の値を両方とも格納する機会となります。以下では、その実装例の一つについて詳しく見ていきましょう。

他の用途を探したところあまり見つけられませんでした。以下に載っている教科書(p.86)にはいくつか提案が挙げられています:

一つの可能性としては、記号式解析器の中で NaN を記号として用いることです。別の案としては、NaN を欠測データ値として使い、ペイロードを欠測データの源泉またはクラスを示すために利用することです。

著者が何か具体的なことを持っていた可能性はありますが、記号としての利用や欠測データの源泉示唆のための実装は見つけることができませんでした。もし NaN ペイロードの他の実用的な利用法を知っている方がいらっしゃいましたら、ぜひお聞かせください!

では、JavaScriptCore がペイロードを使って型情報を格納する方法を見てみましょう:

実践におけるペイロード!JavaScriptCore を探る

ここでは「NaN-boxing」と呼ばれる技術の実装を調べます。NaN-boxing では、言語内のすべての値とその型タグを 64 ビットで表現します。有効な倍精度浮動小数点値は IEEE 754 表現のまま残されますが、NaN のペイロードの余分なスペースには、言語内の他のすべての値と、そのペイロードの型を示すタグが格納されます。「数ではない」という代わりに、「倍精度浮動小数点ではないが、『何か別の型』である」と言い換えるようなイメージです。

ここでは JavaScriptCore(JSC)の NaN-boxing の実装を見ていますが、JSC だけが他型の値を NaN に格納する産業用実装ではありません。例えば Mozilla の SpiderMonkey JavaScript 実装も「nun-boxing」および「pun-boxing」と呼ばれるこの手法を採用しており、LuaJIT はそれを「NaN タギング(NaN-tagging)」と呼んでいます。私が JSC を取り上げる理由は、そのコードに実装を説明する非常に優れたコメントがあるからです。

JSC は WebKit 上で動作する Safari および Adobe クリエイティブスイートなどを実行するための JavaScript 実装です。確認できる限り、我々が検討するコードは現在なお Safari に使用されているものです(2018 年 3 月時点でのファイルの最終更新日は 18 日前でした)。

以下のファイルを調べます。NaN-boxing の仕組みは、非浮動小数点型(ポインタ、整数、ブール値など)を持つ場合はそのペイロードに格納し、上位ビットを使ってペイロードの型を符号化するところにあります。倍精度浮動小数点の場合、ペイロードとして 51 ビット利用できるので、そこに収まるあらゆる値を格納できます。特に注目すべきは、32 ビットの整数と、現在の x86-64 アーキテクチャにおけるポインタ幅である 48 ビットのポインタを格納できることです。つまり、言語内のすべての値を 64 ビットで表現することができるようになります。

付記:ECMAScript 標準によると、JavaScript には原始的な整数データ型が存在せず、すべてが倍精度浮動小数点です。なぜ JS 実装が整数を表現したいのでしょうか?一つの見事な理由は、整数演算がハードウェア上で非常に高速に行えること、また多くの数値値が実際には整数として使われることです。顕著な例は、配列全体を反復する for ループ内のインデックス変数です。また ECMAScript 規格によれば、配列の要素数は 2^32 に制限されているため、配列のインデックス変数を NaN ペイロードとして 32 ビット整数で格納することも安全です。

使用されている符号化スキームは以下の通りです:

  • 上位 16 ビットは符号化した JSValue の型を示す:
    • Pointer { 0000:PPPP:PPPP:PPPP / 0001:::**** Double { ... \ FFFE:::**** Integer { FFFF:0000:IIII:IIII

私たちが実装したスキームでは、倍精度値を符号化する際に 64 ビット整数加算により 2^48 を加算します。この操作後、符号化した任意の倍精度値は 0x0000 もしくは 0xFFFF で始まることはありません。 後続の浮動小数点演算を行う前に、必ずこの逆操作を適用して値を復元する必要があります。

このコメントによれば、異なる値の範囲が異なるオブジェクトタイプを表すために使用されていますが、注目すべきはこのビット範囲は IEEE-754 で定義されたものと一致していません。例えば倍精度浮動小数点の有効な qNaN については:

1 符号ビット | 11 指数ビット | 52 有効数字ビット 1 | 1 1 1 1 1 1 1 1 1 1 1 | 1 + {51 ビットのペイロード}

バイトごとにグループ化すると: 1 1 1 1 | 1 1 1 1 | 1 1 1 1 | 1 + {51 ビットのペイロード}

これは、以下の範囲内のすべてのビットパターンを表します: 0x F F F F ... から 0x F F F 8 ...

つまり規格によると、有効な倍精度値と qNaN で表現される usual なビット範囲は:

     / 0000:****:****:****

Double { ... \ FFF7:::**** / FFF8:::**** qNaN { ... \ FFFF:::****

となります。コード内のコメントは、表現範囲が標準で定義されているものとずれていることを示しています。これを行う理由はポインタを優先するためです:ポインタは上位 2 バイトがゼロの範囲に占めるため、マスクを適用せずにポインタを操作できます。その結果、ポインタのみは「ボックス化(boxing)」されず、他のすべての値だけがそれになります。このポインタを優先する選択は必ずしも直感的ではありません;SpiderMonkey の実装では範囲をシフトせず、倍精度値を優先しています。

さて、この範囲シフトについて最も簡単に理解できるようにするために、ファイル下部のマスクを見てみましょう:

// This value is 2^48, used to encode doubles such that the encoded value will begin // with a 16-bit pattern within the range 0x0001..0xFFFE. #define DoubleEncodeOffset 0x1000000000000ll

このオフセットは asDouble() 関数で使用されます:

inline double JSValue::asDouble() const { ASSERT(isDouble()); return reinterpretInt64ToDouble(u.asInt64 - DoubleEncodeOffset); }

これにより符号化した倍精度値を規格で定義された通常のビットパターン範囲へシフトします。逆に、asCell() 関数(JSC では「セル」と「ポインタ」はほぼ同義)では、このオフセット適用なしでポインタを直接取得できます:

ALWAYS_INLINE JSCell* JSValue::asCell() const { ASSERT(isCell()); return u.ptr; }

Cool. 実際にはここでの本質はこれだけです。以下に JSC 実装からのいくつかの興味深いエピソードに触れますが、これが NaN-boxing の核心です。

他の値についてはどうでしょうか?

コメントで「上位 2 バイトがゼロならペイロードはポインタである」という部分は嘘でした。あるいは、言い換えると、過度に単純化されたものです。JSC は特定の無効なポインタ値を予約して、ECMAScript 標準で要求される即時値(immediates)を表しています:ブール値、未定義、null です:

  • False:     0x06
    
  • True:      0x07
    
  • Undefined: 0x0a   
    
  • Null:      0x02
    

これらすべては 2 番目のビットが設定されており、これらの即時値の一つであるかを簡単に判定できるようにしています。

また標準では要求されていない 2 つの即時値も表現します:配列の穴(holes)を表すために使用される ValueEmpty(0x00)、削除された値をマークするために使用される ValueDeleted(0x04)。

最後に、Wasm のポインタへの参照も 0x03 で表現しています。

つまり、これらをすべて集めると、JSCにおけるビットパターン符号化の完全な概要は以下のようになります:

  • ValEmpty  {  0000:0000:0000:0000
    
  • Null      {  0000:0000:0000:0002
    
  • Wasm      {  0000:0000:0000:0003
    
  • ValDeltd  {  0000:0000:0000:0004   
    
  • False     {  0000:0000:0000:0006
    
  • True      {  0000:0000:0000:0007
    
  • Undefined {  0000:0000:0000:000a    
    
  • Pointer   {  0000:PPPP:PPPP:PPPP
    
  •            / 0001:****:****:****
    
  • Double    {         ...
    
  •            \ FFFE:****:****:****
    
  • Integer   {  FFFF:0000:IIII:IIII
    

要点

  • IEEE 浮動小数点規格は NaN のペイロードに多くの余白を残しています。これは意図的な設計です。
  • 実際の用途では、これらのペイロードがどう使われているかについては、私が正直言うとあまり分かりません。他の実用例をご存じの方がいらっしゃいましたら、ぜひお聞かせください。
  • その一つの用途が「NaN-boxing」であり、これは言語内の全ての非浮動小数点値とその型情報を NaN のペイロードに格納するという手法です。非常に美しいハックと言えます。

付録:NaN をボックス化するか、しないか

この実装を見るだけで、NaN-boxing が良いアイデアなのか、あるいは「bizzo(奇妙な)」なハックなのかという問いが生まれます。私は動的型付け言語を実装・保守していない者として、この質問に適切に答えられる立場にはありません。しかし、多くのアプローチがあり、それぞれ独自の細かなトレードオフがあることは間違いありません。その前提として、いくつかの長所と短所の概略を示します。

長所: メモリ節約、すべての値がレジスタに収まる、ビットマスク適用が高速であること。 短所: ほぼすべての値をボックス化・アンボックス化する必要があるため実装が難しくなる、検証バグが深刻なセキュリティ脆弱性に転じうる。

NaN-boxing のトレードオフについて、動的型付け言語を実装・保守する者の視点をまとめたより良い議論については、以下の記事をご覧ください。

パフォーマンスの問題 aparte として、JSC で発見された脆弱性についてのこれらのレポートもご覧ください(以下)。これらすべての脆弱性が、もし JSC が他のアプローチを採用していれば防止できたかという点については議論の余地がありますが、少なくとも一つは別の手法を使っていれば防ぐことができていたと考えられます:

この方式では構造体の 8 バイトすべてを制御できますが、他の制限もあります(いくつかの浮動小数点正規化操作は真正のアビトラリーな値を書き込むことを許さず。そうでないと CellTag を作り上げてポインタを任意の値に設定でき、それは恐ろしいことになります。面白いことに、これまではそれが許可されており、最初の Vita WebKit エクスプロイト(CVE-2010-1807)がまさにこれを利用していました!)

JSC のメモリモデルについてさらに詳しく知りたい場合は、以下の非常に詳細な記事もおすすめです。

同じ日のほかのニュース

一覧に戻る →

2026/04/28 6:26

NPM ウェブサイトがダウンしています。 (注:ご提示いただいたテキストは、元の改行・余白・記号なしの状態を維持したまま整理済みです。特定の状況(例:障害報告時の注意喚起など)を想定している場合は、以下のような形式もご参照ください。) **NPM ウェブサイトがアクセス不能になっています**

## Japanese Translation: 2026 年 4 月 27 日にウェブサイトの障害が解消されていないものの、npm エコシステムは機能上正常に動作し続けています。`www.npmjs.com` の利用ができなかった一方で、パッケージのインストール、公開、検索、セキュリティ監査、およびレプリケーションフィードといった重要なサービスは現在「Operational(運用中)」の状態です。過去 90 日間の稼働メトリクスは堅牢なパフォーマンスを示しており、ウェブサイト以外のサービスでは稼働率が 100%、ウェブサイトでは 99.92% であり、これは 4 月 13 日から 26 日の間にはインシデントが起きていなかった安定期と対照的です。本件は、これが軽微な不具合なのかより深く対応が必要なのかを調査しており、npm に依存している企業が主要なワークフローが影響を受けていないため自信を持って進めることができます。

2026/04/28 5:44

トロントでの逮捕:3人の男性が、SMS ブラスト関連の事件で容疑から 44 の起訴罪状に直面している

## Japanese Translation: 「Project Lighthouse」のもと、トロント警察は、RCMP およびその他の機関と連携し、SMS ブラスターを関与した画期的なサイバー犯罪の捜査を進めています。これは、カナダでこの特定の攻撃ベクトルの初例となります。捜査は 2025 年 11 月に、セキュリティパートナーがトロント市中心部で稼働していたデバイスの存在を当局に通報したことから開始されました。このモバイル脅威は数か月の間にグレート・トロント・エリアの複数の車両から実行され、1300 万件を超える接続を妨害し、端末を正当なネットワークから切断して、銀行クレデンシャルを奪おうと設計された偽サイトへと誘導しました。準副頭長の Rob Johnson 氏は、この攻撃が 9-1-1 などの緊急サービスに影響を与える恐れがあり、なりすましや盗難の重大なリスクをもたらすと警告しました。3 月 31 日、警察はマークハムとハミルトンで捜索令状を実行し、2 人の容疑者から複数のブラスターを没収した一方、3 目の容疑者は 4 月 21 日に自首しました。この 3 人は現在、44 の告訴に直面しています。当局は、カナダではこの技術が新しいものの、犯罪者の個人データを収集しようとする意図自体は古いものであると強調しています。

2026/04/28 2:45

Easyduino:KiCAD 用のオープンソース PCBA 開発ボード

## Japanese Translation: The Easyduino プロジェクトは、マイコン開発基板における歴史的な断片化に対処するため、Arduino(Uno/Nano)、ESP32/ESP32 S3、Raspberry Pi Pico、STM32 Bluepill といった一般的な MCU 向けにオープンソースかつ KiCad ベースの設計を提供する。Eagle や Altium といった地域固有のツールに依存していた以前のバージョンとは異なり、Easyduino は標準化された 4 レイヤ銅スタックアップ(JLC04161H-7628)を通じてプラットフォーム間でソフトウェア、言語、慣習を統一し、配線の簡素化を実現する。部品は市場での入手可能性とコストに適応され、例えばオリジナルの UNO の USB シリアル変換チップの代わりに ATmega16U2 を使用したり、高価な 01005 パッシブ部品を避けるなどの対応が取られている。各プロジェクトフォルダには、メインの KiCad ファイル、README、必要に応じて非標準フットプリントライブラリ、および BOM(JLCPB が読み取れる Centroid ファイルを含む)や主要部品のデータシート、Gerbers、PDF スケーマ/PCB、写真が含まれる ProductionFiles ディレクトリが用意されている。開発は KiCad v8.0.0 で行われ、更新とテストは KiCad v10 で実施された。Jobsets は生産データの生成を簡素化する。ユーザーは最新版の KiCad をインストールし、ZIP ファイルをダウンロードするか Git を経由してクローンし、変更を行う際は「git add」で全体を追加する必要があることに注意せよ(KiCad v10 の Git ツールには制限があるため)。すべてのボードは CERN Open Hardware Licence Version 2 – Permissive の下で公開されており、ライセンスのコピーを含めれば必須のソースコード開示なしに商用利用が可能である。今後の作業としては、v1.1 RP2040 および ESP32S3 ボードの注文とテストならびに nRF52840 および RP2350A ドングルを開発する予定がある。クレジットは、KiCad に関するヒントを提供し、地上から v1.1 RP2040 ボードを新規設計した winsrrow に贈られる。ハードウェアの作成を全球でよりアクセス可能で一貫性のあるものにするという使命を継続する。

# NAN(Not a Number)の秘めたる生活 NAN(Not a Number)は、コンピュータシステムにおいて数値演算の結果が未定義であるか、表現不可能であることを示す特別な浮動小数点数です。名前には「単なる『数ではない』もの」という印象を与えるかもしれませんが、実際には Python や JavaScript、C++ といったプログラミング言語における数学的な整合性を維持する上で、極めて重要な役割を果たしています。 ## NAN とは何か? NAN は **Not a Number**(数ではない)の略称であり、浮動小数点算術のための IEEE 754 標準において導入されました。他の数値とは異なり、NAN は以下のような独特の性質を備えています: - `NaN == NaN` は常に `False` です(自身と等しいことはありません)。 - NAN を含むあらゆる比較演算の結果は `False` となります。 - 明示的に処理されない限り、計算結果に伝播します。 ### NAN が生じる主な原因 | 操作 | 例 | 結果 | |------|-----|------| | ゼロでの除法(場合による) | `0 / 0` | NAN | | 負数の平方根 | `sqrt(-1)` | NAN | | 非正数の対数 | `log(-5)` | NAN | | 無効な型変換 | `"abc" * 2`(一部の言語) | NAN | ## コード内での NAN の処理方法 ### Python の例 ```python import math # NAN の作成 result = 0 / 0 # nan が返される print(result) # 出力: nan # NAN の検出 if math.isnan(result): print("これは有効な数値ではありません") # try-except やチェックを用いた安全な計算処理 def safe_divide(a, b): if b == 0: return None # または必要に応じて別の方法で対応 return a / b ``` ### JavaScript の例 ```javascript const result = NaN; console.log(typeof result); // "number" if (Number.isNaN(result)) { console.log("結果は数値ではありません"); } // 安全な除法関数 function safeDivide(a, b) { if (b === 0) return null; return a / b; } ``` ## なぜ NAN が存在するのか? NAN は、以下の区別を明確にするために存在します: 1. **エラー**(例:ゼロでの除法) 2. **未定義の結果**(例:`0/0`) 3. **表現不可能な値**(例:実数系における `sqrt(-1)`) この区別により、プログラムは問題のある計算を後で確認できるようにしながらも、健全に動作し続けることができます。 ## 推奨されるベストプラクティス - 演算を実行する前に、必ず入力値を検証してください。 - `x == NaN` ではなく、`math.isnan()`(Python)または `Number.isNaN()`(JavaScript)などのライブラリ関数を使用してください。 - データパイプラインの早期段階で NAN を処理し、沈黙型の失敗を未然に防ぎましょう。 - 文脈に応じて、NAN を意味のあるデフォルト値(例:0、null、特定のフラグ)に置き換えることも検討してください。 --- NAN の秘めたる生活を理解することは、あらゆるプログラミング環境において、より堅牢で予測可能な数値コードを記述するための開発者の助けとなります。 | そっか~ニュース