第一 数字

第一 数字

    计算机正如其名,从诞生之日,就是为了进行快速地数值计算,主要用于炮弹的弹道计算。  

为了搞清楚计算机的工作原理,我们首先要了解数字(尤其是整数)在计算机中是怎么表示的。  

编码方式

  我们知道计算机中数据都是以0、1组成的二进制进行编码、计算、存储、传输的。二进制编码又分为:原码、补码、反码几种编码方式。

原码

反码

补码

掩码

所谓原码就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。

反码表示法规定:

正数的反码与其原码相同;负数的反码是对正数逐位取反,符号位保持为1.

补码表示法规定:正数的补码与其原码相同;负数的补码是在其反码的末位加1。

在计算机系统中,数值一律用**补码**来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。

// 二进制 10001

println!("0b{:08b}",17i8);

// 八进制 21

println!("0o{:08o}",17i8);

// 十六进制 11

println!("0x{:08x}",17i8);


println!("0b{:08b}",0i8);

println!("0b{:08b}",1i8);

println!("0b{:08b}",-1i8);

println!("0b{:08b}",i8::MAX);


println!("0b{:08b}",-2i8);

println!("0b{:08b}",17u8);

println!("0o{:08o}",17u8);

println!("0x{:08x}",17u8);

 

### Excel表格列名(26进制,golang版本)

// ColumnNameToNumber provides a function to convert Excel sheet column name

// (case-insensitive) to int. The function returns an error if column name

// incorrect.

//

// Example:

//

//  excelize.ColumnNameToNumber("AK") // returns 37, nil

func ColumnNameToNumber(name string) (int, error) {

    if len(name) == 0 {

        return -1, newInvalidColumnNameError(name)

    }

    col := 0

    multi := 1

    for i := len(name) - 1; i >= 0; i-- {

        r := name[i]

        if r >= 'A' && r <= 'Z' {

            col += int(r-'A'+1) * multi

        } else if r >= 'a' && r <= 'z' {

            col += int(r-'a'+1) * multi

        } else {

            return -1, newInvalidColumnNameError(name)

        }

        multi *= 26

    }

    if col > MaxColumns {

        return -1, ErrColumnNumber

    }

    return col, nil

}


// ColumnNumberToName provides a function to convert the integer to Excel

// sheet column title.

//

// Example:

//

//  excelize.ColumnNumberToName(37) // returns "AK", nil

func ColumnNumberToName(num int) (string, error) {

    if num < MinColumns || num > MaxColumns {

        return "", ErrColumnNumber

    }

    var col string

    for num > 0 {

        col = string(rune((num-1)%26+65)) + col

        num = (num - 1) / 26

    }

    return col, nil

}

 

### Excel表格列名(26进制,rust版本)

 

const MIN_COLUMNS: usize = 1;

const MAX_COLUMNS: usize = 16384;

/// The column number convert to column name

fn column_number_to_name(num: usize) -> std::string::String {

    if num < MIN_COLUMNS || num > MAX_COLUMNS {

        return "".to_string();

    }

    let mut ret = num;

    let mut col = std::string::String::new();

    while ret > 0 {

        let ch = ((ret - 1) % 26 + 65) as u8;

        ret = (ret - 1) / 26;

        col.insert(0, ch as char);

    }


    col

}


///

/// column name convert to column number

fn column_name_to_number(name: std::string::String) -> usize {

    let len = name.len();

    if len == 0 {

        return 0;

    }

    let mut col = 0;

    let bytes = name.as_bytes();

    let mut i = len - 1;

    let mut multi = 1;

    loop {

        let ch = bytes[i];

        if ch >= b'A' && ch <= b'Z' {

            col += multi * (ch - b'A' + 1) as usize;

        } else if ch >= b'a' && ch <= b'z' {

            col += multi * (ch - b'a' + 1) as usize;

        } else {

            return 0;

        }


        if i < 1 {

            break;

        }

        i -= 1;

        multi *= 26;

    }

    if col > MAX_COLUMNS {

        return 0;

    }


    col

}

编码转换

原码 => 反码 =>补码

原码=>补码

(1)正整数的补码是其二进制表示,与原码相同。

(2)求负整数的补码,将其原码除符号位外的所有位取反(0变1,1变0,符号位为1不变)后加1。

补码=>原码

(1)如果补码的符号位为“0”,表示是一个正数,其原码就是补码。

(2)如果补码的符号位为“1”,表示是一个负数,那么求给定的这个补码的补码就是要求的原码。

简而言之:正整数的原码、反码、补码相同;负整数的补码就是在原码的基础上符号位不变,其他位取反(得到反码),然后加1。

以-1为例(假设类型为i8),-1的原码为10000001,反码为11111110,补码为11111111。由此可见反码作为原码和补码相互转换的中间码。

### 力扣实战:1009. 十进制整数的反码

原码通过与掩码进行异或(XOR)运算得到“反码”,注意:这里的“反码”和真正的反码定义是不一样的。

  pub fn bitwise_complement(n: i32) -> i32 {

    if n == 0 {

        return 1;

    }

    let mut num = n;

    let mut mark = 1;

    let mut high_bit = 0;

    while num > 0 {

        num >>= 1;

        high_bit += 1;

    }


    //dbg!(high_bit);

    let mark = match (high_bit == 31) {

        true => i32::MAX - 1,

        false => (1 << high_bit) - 1,

    };


    n ^ mark

    }


    fn main() {

        let n = 911;

        let complement = bitwise_complement(n);

        println!("{:032b}",n);

        println!("{:032b}",complement);

    }

 

大数

### 大整型

数值多大才能称得上天文数字呢?天文数字又有何用呢?

100的阶乘(100!)有多少个零呢?

use num::bigint::{BigInt, ToBigInt};

/// 计算x的阶乘,即x!

fn factorial(x: i32) -> BigInt {

    if let Some(mut facatorial) = 1.to_bigint() {

        for i in 1..(x + 1) {

            facatorial *= i;

        }

        facatorial

    } else {

        panic!("Failed to calculate factorial!");

    }

}


use num::BigUint;

let x = BigUint::parse_bytes(b"786fe10f87d8ddfeeeea9a4a49e63388e3b2a9e1b0a794907908f6123dbf6c6a", 16).unwrap();


 

### 质数

质数

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值