1. 程式人生 > >浮點型和整型在記憶體中的儲存方式

浮點型和整型在記憶體中的儲存方式

(程式碼執行環境:Xcode7.3.1)

先來看這段程式碼

#include <stdio.h>
int main() {
    int a = 0x12345678;
    int i = 0;
    printf("0x%x, 0x%x\n", &a, a);
    for(; i < sizeof(a); i++) {
        printf("0x%x, 0x%x\n",(char *)&a +i, *((char *)&a + i));
    }
    return 0;
}
輸出:
0x5fbff7c8, 0x12345678
0x5fbff7c8, 0x78
0x5fbff7c9, 0x56
0x5fbff7ca, 0x34
0x5fbff7cb, 0x12

得出結論:在記憶體中,數是倒著儲存的;

87 65 43 21

整形的儲存方式
執行此程式碼
我們把Int型別拆開來看,分成4個位元組看(32位)

#include <iostream>
#include <vector>
void c_to_b(unsigned char c, std::vector<int> &ve) { // 十進位制char型別轉換為二進位制
    int st[8];
    for(int index = 7; index >= 0; index--) {
        st[index] = c % 2
; c >>= 1; } for (int index = 0; index < 8; index++) { ve.push_back(st[index]); } } void int_to_char(int interge) { // int型別轉化為char型別,而且以二進位制輸出 std::vector<int> ve; union { int a; struct { unsigned char a1, a2, a3, a4; } st; } un; un.a = interge; c_to_b(un.st.a1, ve); // 明顯體現出。倒著儲存的
c_to_b(un.st.a2, ve); c_to_b(un.st.a3, ve); c_to_b(un.st.a4, ve); for (int index = 0; index < 8; index++) { std::cout << ve[index]; } std::cout << " "; for (int index = 8; index < 16; index++) { std::cout << ve[index]; } std::cout << " "; for (int index = 16; index < 24; index++) { std::cout << ve[index]; } std::cout << " "; for (int index = 24; index < 32; index++) { std::cout << ve[index]; } } int main(int argc, const char * argv[]) { int_to_char(-2); return 0; }
-2 :11111110 11111111 11111111 11111111
    低位                          高位
2:  00000010 00000000 00000000 00000000
-5: 11111011 11111111 11111111 11111111

結論:
1 資料倒著儲存
2 負數在計算機中是以該負數的二進位制的補碼形式
儲存的。
比如2的反碼是 11111101 11111111 11111111 11111111
補碼是(反碼 + 1 ,在低位加1) 11111110 11111111 11111111 11111111
在有符號數中,正數第一位是0,負數第一位是1
(高位位元組的第一位就是符號位)

浮點型的儲存方式
float 單精度浮點型 1位符號位 8為階碼位 23位尾位
double 雙精度浮點型 1位符號位 11位階碼位 52位尾位

以double為例

void d_to_b(double d) { //double轉化為記憶體中的二進位制表示
    std::vector<int> ve;
    union  {
        double a;
        struct  {
            unsigned char a1, a2, a3, a4, a5, a6, a7, a8;
        } b;
    } t;
    t.a = d;
    c_to_b(t.b.a8, ve); // 已經確實是倒著儲存了,這裡手動把他反過來
    c_to_b(t.b.a7, ve);
    c_to_b(t.b.a6, ve);
    c_to_b(t.b.a5, ve);
    c_to_b(t.b.a4, ve);
    c_to_b(t.b.a3, ve);
    c_to_b(t.b.a2, ve);
    c_to_b(t.b.a1, ve);
    std::cout << "符號位:" << ve.at(0) << " ";
    std::cout << "階碼:";
    for (int index = 1; index < 12; index++) {
        std::cout << ve.at(index);
    }
    std::cout << std::endl << "尾碼:";
    for (int index = 12; index < 64; index++) {
        std::cout << ve.at(index);
    }
    std::cout << std::endl;
}
7.3:
符號位:0 階碼:10000000001
尾碼:1101001100110011001100110011001100110011001100110011

7.5:
符號位:0 階碼:10000000001
尾碼:1110000000000000000000000000000000000000000000000000

來看一道題目

printf("%d",7.5f); // 輸出是多少?

(在VS2005上執行的時候是0 ,在Xcode裡是一堆數)

解釋一下為什麼是0,7.5f在記憶體中的儲存已經知道了,而%d是讀取32位,很明顯尾數的7.5f都是0

也不是所有浮點數這樣輸出都是0,試試7.4

在Mac中嘗試了一下,。。。竟然是隨機數。。。神奇的事情,有待研究。

指標的應用

指標是從低位開始的

int main(int argc, const char * argv[]) {
    int num = 1;
    int *p1 = &num;
    char *p2 = p1;
    char *p3 = p2 + 1;
    *p3 = 3;
    printf("%d", *p1);

    return 0;
}
// 低位                        高位
// 00000001 00000000 00000000 00000000
// p1
// p2
//          p3
// 00000001 00000011 00000000 00000000
// 倒回來讀00000000 00000000 00000011 00000001 = 512+256+1

相關推薦

記憶體儲存方式

(程式碼執行環境:Xcode7.3.1) 先來看這段程式碼 #include <stdio.h> int main() { int a = 0x12345678; int i = 0; printf("0x%x, 0x

牛客網——華為機試(題15:求int正整數在記憶體儲存時1的個數)(Java)

題目描述: 輸入一個int型的正整數,計算出該int型資料在記憶體中儲存時1的個數。 輸入描述: 輸入一個整數(int型別) 輸出描述:  這個數轉換成2進位制後,輸出1的個數 示例1: 輸入: 5 輸出: 2 程式碼:  import java.ut

資料在計算機記憶體儲存

1、型別的歸類     整型家族:char、unsigned char、signed char      //對於char來說,標準裡並不預設其為有符號還是無符號的,這個結果取決於編譯器                         short ( signed shor

字節數組byte[],數據的轉換——Java代碼

amp gravity img 如何 class 機器 保存 clas -m 近期在寫C++ socket和java socket之間的通信程序,涉及到整數浮點數的傳輸。須要從字節數組還原數據,查了一些資料。總結例如以下 1. 整數和浮點數的機器表示 在機器

整形數int、資料float,在記憶體儲存的表示

引言: 突然想到一個底層問題。 計算機組成原理裡學的:定點整數 定點小數 浮點數; 程式設計裡的基本資料型別int float在記憶體中的儲存形式; 二者究竟的對應關係是? CSDN部落格裡有這樣一句話,“實數在記憶體中以規範化的浮點數存放”,請先理清“實數”是多大範圍再回味這句話! 我在書上看到

MySql 基礎學習筆記 1——概述與基本數據類: 1)TINYINT 2)SMALLINT 3) MEDIUMINT 4)INT 5)BIGINT 主要是大小的差別 圖 :命令

where float 函數名 src ron 編碼方式 永遠 -m mas 一、CMD中經常使用mysql相關命令 mysql -D, --database=name //打開數據庫 --delimiter=name //指定分隔符 -h, --host=na

Java強制型別轉換,把轉為

public class Basic{ public static void main(String[] args){ double a = 10.0; double b = 3.0; System.out.println("a / b = "

Linux環境下分十進位制IP間的相互轉換

本文介紹Linux環境下使用Unix網路程式設計實現點分十進位制和整型ip地址間的相互轉換,以及那些應該規避的問題。 先從示例程式碼講起: //輸入點分十進位制的IP,將其轉換成整型後,再反向轉換進行驗證 #include <string.h>

Java的位運算子(運算元只能是字元資料)

java中的位運算子有:左移(<<)、右移(>>)、無符號右移(>>>)、位與(&)、位或(|)、位非(~)、位異或(^),除位異或是一元操作符外,

Python3學習(三):如何取的上界

今天遇到了一個問題,對一個7元素的列表進行分割,想要分割成三個列表,那麼7/3=2.33333…… 也就是說,一個子列表裡面至少有三個元素。要分成3,3,1的形式,但是怎麼將2.3333333強制轉化為3呢。 我們需要用到math模組。 import math nu

C# 顏色值轉換

    直接貼程式碼:     /// <summary> /// 將顏色轉換為整形值 /// </summary> /// <param name="color"></param>

c語言字元的自動型別轉換

char a = -1; //機器碼為0xff unsigned char b = 254; //機器碼0xfe if (a <= b){ printf("a <= b\n"); } else{ printf("a > b\n"); }   上述程式碼輸出結果:

golang基礎學習-字串互轉

在golang語言中字串和整數之間的轉換相比PHP有點複雜。剛學習的人,尤其學過PHP,秒級可以搞定的事情, 這裡卻要使用strcov包中函式轉換,orz~~~~。沒辦法入了golang的大門,就要繼續探究下去。 1.字串轉成整型 func Atoi(s strin

Linux Bash Shell學習(十五:變數型別運算

                  本文也即《Learning the bash Shell》3rd Edition的第六章Command-Line Options and Typed varilables之讀書筆記之二,但我們將不限於此。  在之前,我們涉及的變數基本上是字串,也有整數,例如便是引數個數的$

Codeforces Round #280 (Div. 2) D:二分+點數模型轉為模型 E:數學(取模)

比賽地址: http://codeforces.com/contest/492 官方題解: Codeforces Round #280 (Div. 2) Editorial By Wild_Hamster, 11 hours ago, translation

算術轉化提升的奧祕

首先請大家先思考一下3個問題,問題相互之間是有關聯的。 1,整型字面值是屬於整型家族9種中的哪一種呢? 2,什麼是算術轉換?如何轉換的? 3,什麼是整型提升?如何提升的?為什麼會有整形提升? 下面解答上述問題。 1,整型字面值是屬於整型家族9種中的哪一種呢? 答案取決於

點數轉成intval

$n="19.99"; var_dump(intval($n*100)); // int(1998) var_dump(strval($n*100)); // string(4) "1999" var

c++的多物件模型

1.什麼是多型? 多型顧名思義,就是“多種形態” 在c++中,我們是通過虛擬函式來實現多型的 那麼什麼是虛擬函式呢? 虛擬函式就是在類的成員函式的前面加上virtual關鍵字,那麼該成員函式就是虛擬函式 在c++中多型形成的條件是什麼呢? 1.虛擬函式的重寫; 2.父類的指

華為oj 字串個數統計&&數字顛倒&&字串翻轉&&字元逆序&&求int資料在記憶體儲存時1的個數

同樣只上程式,都是簡單題 #include<iostream> using namespace std; int main() { int in[128], count = 0; char n,temp[100]; memset(in, 0, sizeo

不用庫函式進行字串資料的相互轉換

//  字串轉換成整型資料 double stoi (char* string = NULL){ if (string == NULL) throw 1;  // 空字串判斷  int i = 0; d