浮動小数点数と16進数の相互変換方法【JavaScript/Python完全解説】
![]() |
20万件以上の案件から、副業に最適なリモート・週3〜の案件を一括検索できるプラットフォーム。プロフィール登録でAIスカウトが自動的にマッチング案件を提案。市場統計や単価相場、エージェントの口コミも無料で閲覧可能なため、本業を続けながら効率的に高単価の副業案件を探せます。フリーランスボード |
| |
週2〜3日から働ける柔軟な案件が業界トップクラスの豊富さを誇るフリーランスエージェント。エンド直契約のため高単価で、週3日稼働でも十分な報酬を得られます。リモートや時間フレキシブルな案件も多数。スタートアップ・ベンチャー中心で、トレンド技術を使った魅力的な案件が揃っています。専属エージェントが案件紹介から契約交渉までサポート。利用企業2,000社以上の実績。ITプロパートナーズ |
| |
10,000件以上の案件を保有し、週3日〜・フルリモートなど柔軟な働き方に対応。高単価案件が豊富で、報酬保障制度(60%)や保険料負担(50%)など正社員並みの手厚い福利厚生が特徴。通勤交通費(月3万円)、スキルアップ費用(月1万円)の支給に加え、リロクラブ・freeeが無料利用可能。非公開案件80%以上、支払いサイト20日で安心して稼働できます。Midworks |
目次
浮動小数点数のバイナリ表現を16進数文字列として扱う処理は、システムプログラミングやデータ解析において重要です。この記事では、float値と16進数表現の文字列を相互変換する方法を詳しく解説します。
JavaScript での浮動小数点数と16進数変換
Float32(単精度)の変換
function floatToHex32(num) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setFloat32(0, num, false); // ビッグエンディアン
let hex = '';
for (let i = 0; i < 4; i++) {
hex += view.getUint8(i).toString(16).padStart(2, '0');
}
return hex;
}
function hexToFloat32(hex) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
for (let i = 0; i < 4; i++) {
const byte = parseInt(hex.substr(i * 2, 2), 16);
view.setUint8(i, byte);
}
return view.getFloat32(0, false);
}
// 使用例
console.log(floatToHex32(3.14159)); // "40490fdb"
console.log(hexToFloat32("40490fdb")); // 3.1415901184082031
Float64(倍精度)の変換
function floatToHex64(num) {
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setFloat64(0, num, false);
let hex = '';
for (let i = 0; i < 8; i++) {
hex += view.getUint8(i).toString(16).padStart(2, '0');
}
return hex;
}
function hexToFloat64(hex) {
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
for (let i = 0; i < 8; i++) {
const byte = parseInt(hex.substr(i * 2, 2), 16);
view.setUint8(i, byte);
}
return view.getFloat64(0, false);
}
// 使用例
console.log(floatToHex64(3.14159)); // "400921fb54442d18"
console.log(hexToFloat64("400921fb54442d18")); // 3.14159
Python での浮動小数点数と16進数変換
structモジュールを使用
import struct
def float_to_hex32(num):
"""32ビット浮動小数点数を16進数文字列に変換"""
packed = struct.pack('>f', num) # ビッグエンディアン
return packed.hex()
def hex_to_float32(hex_str):
"""16進数文字列を32ビット浮動小数点数に変換"""
bytes_data = bytes.fromhex(hex_str)
return struct.unpack('>f', bytes_data)[0]
def float_to_hex64(num):
"""64ビット浮動小数点数を16進数文字列に変換"""
packed = struct.pack('>d', num)
return packed.hex()
def hex_to_float64(hex_str):
"""16進数文字列を64ビット浮動小数点数に変換"""
bytes_data = bytes.fromhex(hex_str)
return struct.unpack('>d', bytes_data)[0]
# 使用例
print(float_to_hex32(3.14159)) # "40490fdb"
print(hex_to_float32("40490fdb")) # 3.1415901184082031
print(float_to_hex64(3.14159)) # "400921fb54442d18"
print(hex_to_float64("400921fb54442d18")) # 3.14159
包括的な変換クラス
JavaScript版
class FloatHexConverter {
static float32ToHex(num) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setFloat32(0, num, false);
return Array.from(new Uint8Array(buffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
static hexToFloat32(hex) {
if (hex.length !== 8) {
throw new Error('32ビットfloatには8文字の16進数が必要です');
}
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
for (let i = 0; i < 4; i++) {
view.setUint8(i, parseInt(hex.substr(i * 2, 2), 16));
}
return view.getFloat32(0, false);
}
static float64ToHex(num) {
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setFloat64(0, num, false);
return Array.from(new Uint8Array(buffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
static hexToFloat64(hex) {
if (hex.length !== 16) {
throw new Error('64ビットfloatには16文字の16進数が必要です');
}
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
for (let i = 0; i < 8; i++) {
view.setUint8(i, parseInt(hex.substr(i * 2, 2), 16));
}
return view.getFloat64(0, false);
}
}
Python版
import struct
class FloatHexConverter:
@staticmethod
def float32_to_hex(num):
"""32ビット浮動小数点数を16進数文字列に変換"""
try:
packed = struct.pack('>f', num)
return packed.hex()
except (struct.error, OverflowError) as e:
raise ValueError(f"変換エラー: {e}")
@staticmethod
def hex_to_float32(hex_str):
"""16進数文字列を32ビット浮動小数点数に変換"""
if len(hex_str) != 8:
raise ValueError("32ビットfloatには8文字の16進数が必要です")
try:
bytes_data = bytes.fromhex(hex_str)
return struct.unpack('>f', bytes_data)[0]
except (ValueError, struct.error) as e:
raise ValueError(f"変換エラー: {e}")
@staticmethod
def float64_to_hex(num):
"""64ビット浮動小数点数を16進数文字列に変換"""
try:
packed = struct.pack('>d', num)
return packed.hex()
except (struct.error, OverflowError) as e:
raise ValueError(f"変換エラー: {e}")
@staticmethod
def hex_to_float64(hex_str):
"""16進数文字列を64ビット浮動小数点数に変換"""
if len(hex_str) != 16:
raise ValueError("64ビットfloatには16文字の16進数が必要です")
try:
bytes_data = bytes.fromhex(hex_str)
return struct.unpack('>d', bytes_data)[0]
except (ValueError, struct.error) as e:
raise ValueError(f"変換エラー: {e}")
特殊値の処理
JavaScript
function handleSpecialValues() {
console.log("正の無限大:", FloatHexConverter.float32ToHex(Infinity));
console.log("負の無限大:", FloatHexConverter.float32ToHex(-Infinity));
console.log("NaN:", FloatHexConverter.float32ToHex(NaN));
console.log("ゼロ:", FloatHexConverter.float32ToHex(0.0));
console.log("負のゼロ:", FloatHexConverter.float32ToHex(-0.0));
}
Python
import math
def handle_special_values():
print("正の無限大:", FloatHexConverter.float32_to_hex(float('inf')))
print("負の無限大:", FloatHexConverter.float32_to_hex(float('-inf')))
print("NaN:", FloatHexConverter.float32_to_hex(float('nan')))
print("ゼロ:", FloatHexConverter.float32_to_hex(0.0))
print("負のゼロ:", FloatHexConverter.float32_to_hex(-0.0))
エンディアンの考慮
リトルエンディアン対応
// JavaScript
function floatToHexLE(num) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setFloat32(0, num, true); // リトルエンディアン
return Array.from(new Uint8Array(buffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
function hexToFloatLE(hex) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
for (let i = 0; i < 4; i++) {
view.setUint8(i, parseInt(hex.substr(i * 2, 2), 16));
}
return view.getFloat32(0, true); // リトルエンディアン
}
# Python
def float_to_hex_le(num):
"""リトルエンディアンで変換"""
packed = struct.pack('<f', num) # リトルエンディアン
return packed.hex()
def hex_to_float_le(hex_str):
"""リトルエンディアンで変換"""
bytes_data = bytes.fromhex(hex_str)
return struct.unpack('<f', bytes_data)[0]
IEEE 754形式の詳細解析
ビット構造の表示
function analyzeFloat32Bits(num) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setFloat32(0, num, false);
const bits = view.getUint32(0, false);
const sign = (bits >>> 31) & 1;
const exponent = (bits >>> 23) & 0xFF;
const mantissa = bits & 0x7FFFFF;
return {
hex: bits.toString(16).padStart(8, '0'),
sign: sign,
exponent: exponent,
mantissa: mantissa,
binary: bits.toString(2).padStart(32, '0')
};
}
// 使用例
console.log(analyzeFloat32Bits(3.14159));
def analyze_float32_bits(num):
"""32ビットfloatのビット構造を解析"""
packed = struct.pack('>f', num)
bits = struct.unpack('>I', packed)[0]
sign = (bits >> 31) & 1
exponent = (bits >> 23) & 0xFF
mantissa = bits & 0x7FFFFF
return {
'hex': f"{bits:08x}",
'sign': sign,
'exponent': exponent,
'mantissa': mantissa,
'binary': f"{bits:032b}"
}
# 使用例
print(analyze_float32_bits(3.14159))
バリデーション付き変換関数
JavaScript版
class SafeFloatHexConverter {
static validateHex(hex, expectedLength) {
if (typeof hex !== 'string') {
throw new Error('16進数文字列である必要があります');
}
if (hex.length !== expectedLength) {
throw new Error(`${expectedLength}文字の16進数が必要です`);
}
if (!/^[0-9a-fA-F]+$/.test(hex)) {
throw new Error('無効な16進数文字列です');
}
}
static safeFloat32ToHex(num) {
if (!Number.isFinite(num) && !Number.isNaN(num)) {
console.warn('特殊値を変換しています:', num);
}
return FloatHexConverter.float32ToHex(num);
}
static safeHexToFloat32(hex) {
this.validateHex(hex, 8);
return FloatHexConverter.hexToFloat32(hex);
}
}
Python版
import re
class SafeFloatHexConverter:
@staticmethod
def validate_hex(hex_str, expected_length):
"""16進数文字列の妥当性をチェック"""
if not isinstance(hex_str, str):
raise ValueError("16進数文字列である必要があります")
if len(hex_str) != expected_length:
raise ValueError(f"{expected_length}文字の16進数が必要です")
if not re.match(r'^[0-9a-fA-F]+, hex_str):
raise ValueError("無効な16進数文字列です")
@staticmethod
def safe_float32_to_hex(num):
"""安全な32ビット浮動小数点数変換"""
import math
if math.isinf(num) or math.isnan(num):
print(f"警告: 特殊値を変換しています: {num}")
return FloatHexConverter.float32_to_hex(num)
@staticmethod
def safe_hex_to_float32(hex_str):
"""安全な16進数から32ビット浮動小数点数変換"""
SafeFloatHexConverter.validate_hex(hex_str, 8)
return FloatHexConverter.hex_to_float32(hex_str)
実用的な使用例
データシリアライゼーション
class FloatSerializer {
static serialize(floats) {
return floats.map(f => FloatHexConverter.float32ToHex(f)).join('');
}
static deserialize(hexString) {
const floats = [];
for (let i = 0; i < hexString.length; i += 8) {
const hex = hexString.substr(i, 8);
if (hex.length === 8) {
floats.push(FloatHexConverter.hexToFloat32(hex));
}
}
return floats;
}
}
// 使用例
const data = [3.14, 2.71, 1.41];
const serialized = FloatSerializer.serialize(data);
console.log("シリアライズ:", serialized);
console.log("デシリアライズ:", FloatSerializer.deserialize(serialized));
class FloatSerializer:
@staticmethod
def serialize(floats):
"""浮動小数点数配列を16進数文字列にシリアライズ"""
return ''.join(FloatHexConverter.float32_to_hex(f) for f in floats)
@staticmethod
def deserialize(hex_string):
"""16進数文字列から浮動小数点数配列にデシリアライズ"""
floats = []
for i in range(0, len(hex_string), 8):
hex_chunk = hex_string[i:i+8]
if len(hex_chunk) == 8:
floats.append(FloatHexConverter.hex_to_float32(hex_chunk))
return floats
# 使用例
data = [3.14, 2.71, 1.41]
serialized = FloatSerializer.serialize(data)
print("シリアライズ:", serialized)
print("デシリアライズ:", FloatSerializer.deserialize(serialized))
パフォーマンステスト
JavaScript版
function performanceTest() {
const testData = Array.from({length: 10000}, () => Math.random() * 1000);
console.time('Float to Hex conversion');
const hexData = testData.map(FloatHexConverter.float32ToHex);
console.timeEnd('Float to Hex conversion');
console.time('Hex to Float conversion');
const backToFloat = hexData.map(FloatHexConverter.hexToFloat32);
console.timeEnd('Hex to Float conversion');
}
import time
def performance_test():
import random
test_data = [random.random() * 1000 for _ in range(10000)]
start_time = time.time()
hex_data = [FloatHexConverter.float32_to_hex(f) for f in test_data]
print(f"Float to Hex変換: {time.time() - start_time:.4f}秒")
start_time = time.time()
back_to_float = [FloatHexConverter.hex_to_float32(h) for h in hex_data]
print(f"Hex to Float変換: {time.time() - start_time:.4f}秒")
まとめ
浮動小数点数と16進数の相互変換は、システム間でのデータ交換やバイナリ形式での保存において重要な技術です。JavaScriptではArrayBufferとDataView、Pythonではstructモジュールを使用することで、効率的で正確な変換が可能です。エラーハンドリングやバリデーションを含めた実装により、堅牢なシステムを構築できます。
■「らくらくPython塾」が切り開く「呪文コーディング」とは?
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座
![]() |
20万件以上の案件から、副業に最適なリモート・週3〜の案件を一括検索できるプラットフォーム。プロフィール登録でAIスカウトが自動的にマッチング案件を提案。市場統計や単価相場、エージェントの口コミも無料で閲覧可能なため、本業を続けながら効率的に高単価の副業案件を探せます。フリーランスボード |
| |
週2〜3日から働ける柔軟な案件が業界トップクラスの豊富さを誇るフリーランスエージェント。エンド直契約のため高単価で、週3日稼働でも十分な報酬を得られます。リモートや時間フレキシブルな案件も多数。スタートアップ・ベンチャー中心で、トレンド技術を使った魅力的な案件が揃っています。専属エージェントが案件紹介から契約交渉までサポート。利用企業2,000社以上の実績。ITプロパートナーズ |
| |
10,000件以上の案件を保有し、週3日〜・フルリモートなど柔軟な働き方に対応。高単価案件が豊富で、報酬保障制度(60%)や保険料負担(50%)など正社員並みの手厚い福利厚生が特徴。通勤交通費(月3万円)、スキルアップ費用(月1万円)の支給に加え、リロクラブ・freeeが無料利用可能。非公開案件80%以上、支払いサイト20日で安心して稼働できます。Midworks |



