Go/uint32
表示
< Go
Goのuint32について
[編集]Goにおけるuint32は32ビット符号なし整数型を表す事前宣言された型です。4バイトのサイズを持ち、0から4294967295までの値を格納できます。
基本情報
[編集]uint32は32ビット(4バイト)の符号なし整数型- 値の範囲: 0 から 4294967295 (2^32-1)
- メモリ上での表現: 32ビット
- IPアドレス、ファイルサイズ、タイムスタンプなどの表現によく使用される
他のキーワードとの組み合わせ
[編集]変数宣言との組み合わせ
[編集]var fileSize uint32 = 1048576 count := uint32(100000) // 型推論による短縮形 maxValue := uint32(4294967295)
定数定義との組み合わせ
[編集]const MAX_FILE_SIZE uint32 = 100 * 1024 * 1024 // 100MB const BUFFER_SIZE uint32 = 65536 const EPOCH_OFFSET uint32 = 2208988800 // Unix epoch offset
関数パラメータと戻り値
[編集]func calculateChecksum(data []byte) uint32 { var sum uint32 for _, b := range data { sum += uint32(b) } return sum } func getCurrentTimestamp() uint32 { return uint32(time.Now().Unix()) }
型変換
[編集]i := 1000000 size := uint32(i) // int から uint32 への変換 f := 3.14159265359 rounded := uint32(f) // float から uint32 への変換(小数点以下切り捨て) // より大きな型からの変換 var bigNum uint64 = 5000000000 smallNum := uint32(bigNum) // 値が範囲外の場合は下位32ビットのみが保持される
配列とスライス
[編集]var sizes [100]uint32 // uint32型の固定長配列 buffer := make([]uint32, 1024) // uint32型のスライス timestamps := []uint32{1609459200, 1640995200, 1672531200} // リテラルで初期化
マップ
[編集]fileSizes := make(map[string]uint32) fileSizes["document.pdf"] = 2048576 fileSizes["image.jpg"] = 1024000 fileSizes["video.mp4"] = 104857600 ipToID := make(map[uint32]string) ipToID[3232235521] = "192.168.1.1"
構造体のフィールド
[編集]type FileInfo struct { Name string Size uint32 CreatedAt uint32 // Unix timestamp Permissions uint32 } type IPv4Address struct { Address uint32 // IPv4アドレスを32ビット整数で表現 }
ビット操作
[編集]var flags uint32 = 0 // ビットをセット flags |= 1 << 16 // ビットをクリア flags &^= 1 << 10 // ビットをチェック if (flags & (1 << 16)) != 0 { fmt.Println("16番目のビットがセットされています") } // 32ビットを4つの8ビットに分割 var value uint32 = 0x12345678 byte1 := uint8(value >> 24) // 0x12 byte2 := uint8((value >> 16) & 0xFF) // 0x34 byte3 := uint8((value >> 8) & 0xFF) // 0x56 byte4 := uint8(value & 0xFF) // 0x78
一般的なユースケース
[編集]- ファイルサイズとディスク容量管理
type FileSystem struct { TotalSpace uint32 // バイト単位 UsedSpace uint32 FreeSpace uint32 } func (fs *FileSystem) AddFile(size uint32) error { if fs.FreeSpace < size { return fmt.Errorf("insufficient space") } fs.UsedSpace += size fs.FreeSpace -= size return nil } func formatBytes(bytes uint32) string { const unit = 1024 if bytes < unit { return fmt.Sprintf("%d B", bytes) } div, exp := uint32(unit), 0 for n := bytes / unit; n >= unit; n /= unit { div *= unit exp++ } return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp]) }
- IPv4アドレス処理
import ( "encoding/binary" "net" ) func ipToUint32(ip net.IP) uint32 { ip = ip.To4() if ip == nil { return 0 } return binary.BigEndian.Uint32(ip) } func uint32ToIP(n uint32) net.IP { ip := make(net.IP, 4) binary.BigEndian.PutUint32(ip, n) return ip } func isInSubnet(ip, network, mask uint32) bool { return (ip & mask) == (network & mask) } // 使用例 func main() { ip := net.ParseIP("192.168.1.100") ipNum := ipToUint32(ip) fmt.Printf("IP: %s, Numeric: %d\n", ip, ipNum) // サブネットチェック network := ipToUint32(net.ParseIP("192.168.1.0")) mask := uint32(0xFFFFFF00) // /24 if isInSubnet(ipNum, network, mask) { fmt.Println("IP is in subnet") } }
- Unixタイムスタンプ
type Event struct { ID uint32 Name string Timestamp uint32 // Unix timestamp } func CreateEvent(name string) Event { return Event{ ID: generateID(), Name: name, Timestamp: uint32(time.Now().Unix()), } } func (e Event) ToTime() time.Time { return time.Unix(int64(e.Timestamp), 0) } func (e Event) IsExpired(ttlSeconds uint32) bool { current := uint32(time.Now().Unix()) return current > e.Timestamp+ttlSeconds }
- ハッシュ値とチェックサム
import ( "hash/crc32" "hash/fnv" ) func calculateCRC32(data []byte) uint32 { return crc32.ChecksumIEEE(data) } func calculateFNV32(data []byte) uint32 { h := fnv.New32a() h.Write(data) return h.Sum32() } type DataBlock struct { Data []byte Checksum uint32 } func NewDataBlock(data []byte) DataBlock { return DataBlock{ Data: data, Checksum: calculateCRC32(data), } } func (db DataBlock) Verify() bool { return db.Checksum == calculateCRC32(db.Data) }
- メモリプールとオブジェクト管理
type ObjectPool struct { objects map[uint32]interface{} nextID uint32 freeIDs []uint32 maxObjects uint32 } func NewObjectPool(maxObjects uint32) *ObjectPool { return &ObjectPool{ objects: make(map[uint32]interface{}), nextID: 1, freeIDs: make([]uint32, 0), maxObjects: maxObjects, } } func (pool *ObjectPool) Allocate(obj interface{}) (uint32, error) { if uint32(len(pool.objects)) >= pool.maxObjects { return 0, fmt.Errorf("pool is full") } var id uint32 if len(pool.freeIDs) > 0 { id = pool.freeIDs[len(pool.freeIDs)-1] pool.freeIDs = pool.freeIDs[:len(pool.freeIDs)-1] } else { id = pool.nextID pool.nextID++ } pool.objects[id] = obj return id, nil } func (pool *ObjectPool) Free(id uint32) { if _, exists := pool.objects[id]; exists { delete(pool.objects, id) pool.freeIDs = append(pool.freeIDs, id) } }
- バイナリプロトコルとシリアライゼーション
import "encoding/binary" type Header struct { Magic uint32 Version uint32 Length uint32 Flags uint32 Timestamp uint32 } func (h Header) Serialize() []byte { buf := make([]byte, 20) // 5 * 4 bytes binary.LittleEndian.PutUint32(buf[0:], h.Magic) binary.LittleEndian.PutUint32(buf[4:], h.Version) binary.LittleEndian.PutUint32(buf[8:], h.Length) binary.LittleEndian.PutUint32(buf[12:], h.Flags) binary.LittleEndian.PutUint32(buf[16:], h.Timestamp) return buf } func DeserializeHeader(data []byte) Header { if len(data) < 20 { return Header{} } return Header{ Magic: binary.LittleEndian.Uint32(data[0:4]), Version: binary.LittleEndian.Uint32(data[4:8]), Length: binary.LittleEndian.Uint32(data[8:12]), Flags: binary.LittleEndian.Uint32(data[12:16]), Timestamp: binary.LittleEndian.Uint32(data[16:20]), } }
- カウンターとメトリクス
type SystemMetrics struct { RequestCount uint32 ErrorCount uint32 BytesProcessed uint32 UpTimeSeconds uint32 } func (m *SystemMetrics) IncrementRequests() { if m.RequestCount < 4294967295 { m.RequestCount++ } } func (m *SystemMetrics) AddBytesProcessed(bytes uint32) { // オーバーフロー対策 if m.BytesProcessed > 4294967295-bytes { m.BytesProcessed = 4294967295 } else { m.BytesProcessed += bytes } } func (m SystemMetrics) GetErrorRate() float64 { if m.RequestCount == 0 { return 0.0 } return float64(m.ErrorCount) / float64(m.RequestCount) }
- ゲーム開発でのリソース管理
type GameResource struct { ID uint32 Type string LoadedAt uint32 // timestamp MemoryUsage uint32 // bytes RefCount uint32 } type ResourceManager struct { resources map[uint32]*GameResource nextID uint32 totalMemory uint32 maxMemory uint32 } func NewResourceManager(maxMemory uint32) *ResourceManager { return &ResourceManager{ resources: make(map[uint32]*GameResource), nextID: 1, maxMemory: maxMemory, } } func (rm *ResourceManager) LoadResource(resourceType string, memoryUsage uint32) (uint32, error) { if rm.totalMemory+memoryUsage > rm.maxMemory { return 0, fmt.Errorf("insufficient memory") } resource := &GameResource{ ID: rm.nextID, Type: resourceType, LoadedAt: uint32(time.Now().Unix()), MemoryUsage: memoryUsage, RefCount: 1, } rm.resources[rm.nextID] = resource rm.totalMemory += memoryUsage rm.nextID++ return resource.ID, nil } func (rm *ResourceManager) UnloadResource(id uint32) { if resource, exists := rm.resources[id]; exists { rm.totalMemory -= resource.MemoryUsage delete(rm.resources, id) } }
注意点
[編集]- オーバーフロー: 最大値(4294967295)を超えると、0に戻ります(ラップアラウンド)
var x uint32 = 4294967295 x++ // x は 0 になる // オーバーフロー対策 func safeAdd(a, b uint32) (uint32, bool) { if a > 4294967295-b { return 0, false // オーバーフロー } return a + b, true }
- 負の値: 負の値を代入しようとするとコンパイルエラーになります
var size uint32 = -1 // コンパイルエラー
- 範囲外の値: 代入時に自動的に切り捨てられます
var large uint64 = 5000000000 var small uint32 = uint32(large) // 5000000000 % 4294967296 = 705032704
- 演算時の型の考慮: より大きな型との演算では型変換が必要な場合があります
var a uint32 = 2000000000 var b uint32 = 2000000000 // var sum = a + b // オーバーフローの可能性 // 安全な演算 sum64 := uint64(a) + uint64(b) if sum64 > 4294967295 { fmt.Println("オーバーフローが発生しました") }
- Unixタイムスタンプの制限: uint32のUnixタイムスタンプは2038年問題があります
// 2038年1月19日3:14:07 UTCでオーバーフロー var maxUnixTime uint32 = 2147483647 // 2038年問題を回避するには、int64またはtime.Timeを使用 func getCurrentTimestamp64() int64 { return time.Now().Unix() }
- プラットフォーム依存性: 異なるアーキテクチャ間でのバイト順序に注意
import "encoding/binary" func writeUint32(w io.Writer, value uint32, order binary.ByteOrder) error { buf := make([]byte, 4) order.PutUint32(buf, value) _, err := w.Write(buf) return err }
uint32型は、ファイルサイズ、IPアドレス、タイムスタンプ、大きなカウンター、ハッシュ値など、広範囲の数値を効率的に扱う場合に適しています。大きな数値を扱う際は、オーバーフローや2038年問題などの制限に注意して使用することが重要です。