【问题标题】:How to check whether a system is big endian or little endian?如何检查系统是大端还是小端?
【发布时间】:2011-05-10 01:52:38
【问题描述】:

如何判断系统是大端还是小端?

【问题讨论】:

标签: endianness


【解决方案1】:

在 Rust 中(不需要 crates 或 use 语句)

在函数体中:

if cfg!(target_endian = "big") {
    println!("Big endian");
} else {
    println!("Little endian");
}

在函数体之外:

#[cfg(target_endian = "big")]
fn print_endian() {
    println!("Big endian")
}

#[cfg(target_endian = "little")]
fn print_endian() {
    println!("Little endian")
}

这是byteorder crate 在内部所做的:https://docs.rs/byteorder/1.3.2/src/byteorder/lib.rs.html#1877

【讨论】:

  • 第一个例子中应该有一个右花括号而不是方括号。
【解决方案2】:

在 Powershell 中

[System.BitConverter]::IsLittleEndian

【讨论】:

    【解决方案3】:

    n00bs 最佳答案的可编译版本:

    #include <stdio.h>
    
    int main() {
        int n = 1;
    
        // little endian if true
        if(*(char *)&n == 1) {
            printf("Little endian\n");
        } else {
            printf("Big endian\n");
        }   
    }
    

    粘贴到check-endianness.c 并编译运行:

    $ gcc -o check-endianness check-endianness.c
    $ ./check-endianness
    

    整个命令是一个可复制/可粘贴的 bash 脚本,您可以将其粘贴到终端中:

    cat << EOF > check-endianness.c
    #include <stdio.h>
    int main() {
        int n = 1;
        // little endian if true
        if(*(char *)&n == 1) {
            printf("Little endian\n");
        } else {
            printf("Big endian\n");
        }   
    }
    EOF
    
    gcc -o check-endianness check-endianness.c \
     && ./check-endianness \
     && rm check-endianness check-endianness.c
    

    如果您愿意,代码是in a gist here。还有a bash command that you can run that will generate, compile, and clean up after itself

    【讨论】:

      【解决方案4】:

      Nim

      echo cpuEndian
      

      它是从system 模块导出的。

      【讨论】:

        【解决方案5】:

        在 Rust 中(需要 byteorder crate):

        use std::any::TypeId;
        
        let is_little_endian = TypeId::of::<byteorder::NativeEndian>() == TypeId::of::<byteorder::LittleEndian>();
        

        【讨论】:

        • 你现在不需要 crate:#[cfg(target_endian = "little")] 或者如果 cfg!((target_endian = "little") 可以工作。
        【解决方案6】:

        在 C++20 中使用 std::endian:

        #include <bit>
        #include <iostream>
        
        int main() {
            if constexpr (std::endian::native == std::endian::little)
                std::cout << "little-endian";
            else if constexpr (std::endian::native == std::endian::big)
                std::cout << "big-endian";
            else
                std::cout << "mixed-endian";
        }
        

        【讨论】:

          【解决方案7】:

          在 C 中

          #include <stdio.h> 
          
          /* function to show bytes in memory, from location start to start+n*/
          void show_mem_rep(char *start, int n) 
           { 
                int i; 
                for (i = 0; i < n; i++) 
                printf("%2x ", start[i]); 
                printf("\n"); 
           } 
          
          /*Main function to call above function for 0x01234567*/
          int main() 
          { 
             int i = 0x01234567; 
             show_mem_rep((char *)&i, sizeof(i));  
             return 0; 
          } 
          

          上面的程序在小端机器上运行时,输出“67 45 23 01”,而如果在大端机器上运行,则输出“01 23 45 67”。

          【讨论】:

          • 嘿,伙计,这不是你自己的代码,你只是复制粘贴。您至少应该注意代码的来源。
          【解决方案8】:

          使用宏,

          const int isBigEnd=1;
          #define is_bigendian() ((*(char*)&isBigEnd) == 0)
          

          【讨论】:

            【解决方案9】:

            在 Python 中:

            from sys import byteorder
            print(byteorder)
            # will print 'little' if little endian
            

            【讨论】:

              【解决方案10】:

              另一个使用联合的 C 代码

              union {
                  int i;
                  char c[sizeof(int)];
              } x;
              x.i = 1;
              if(x.c[0] == 1)
                  printf("little-endian\n");
              else    printf("big-endian\n");
              

              这与贝尔伍德使用的逻辑相同。

              【讨论】:

              • 我认为这不符合标准:您只能从您上次写入的枚举中读取字段,否则可能出现未定义的行为,还是我弄错了?
              • 工会没有在标准中指定“证明”。这不是正确的解决方案(它可能在特定的操作系统/编译器中意外工作)。
              • 能否解释一下上述程序中的逻辑。如果用 x.1=1 初始化成员变量 i,那么 x.c[0] 是如何变成 1 的。我在这里遗漏了一些要点吗?我的理解是 union 会占用最大数据类型的内存,并取决于我们可以访问它。只能访问一个成员。任何回应都将受到高度评价
              • @VivekSingh 正如你所说,联合获取最大数据类型的内存,并取决于我们可以访问它。因此,两种数据类型的内存都是相同的。所以我们以 int 访问并将其分配为 1。所以在 4 字节中只有 1 字节部分将有单个 1。当我们以 char 访问时,它只需要 1 字节。
              【解决方案11】:

              在 Linux 中,

              static union { char c[4]; unsigned long mylong; } endian_test = { { 'l', '?', '?', 'b' } };
              #define ENDIANNESS ((char)endian_test.mylong)
              
              if (ENDIANNESS == 'l') /* little endian */
              if (ENDIANNESS == 'b') /* big endian */
              

              【讨论】:

              • 它与 Neeraj 的版本有何不同?
              【解决方案12】:

              在 C、C++ 中

              int n = 1;
              // little endian if true
              if(*(char *)&n == 1) {...}
              

              另请参阅:Perl version

              【讨论】:

              • 不错的答案,但这提供了一个很好的图表:stackoverflow.com/a/12792301/803801
              • 你能告诉我为什么我们不能只使用(char)n == 1 吗?为什么我们必须获取地址,将其转换为char 指针,然后取消引用?这不会隐式完成(char)n 使用吗?
              • @J...S 仅使用字符转换似乎工作正常。不过我还没有在大端系统上测试过。
              • 只使用 char 是行不通的。因为转换为 char 会导致系统从 int 转换为 char。它总是会返回 true。使用转换为指针和取消引用将指针放置到 N 的第一个字节,然后取消引用第一个字节。
              • 演员表不是转换。如果是 Big Endian,那么 N 的第一个字节是零 - 那么这如何导致 true?
              【解决方案13】:

              C++ 解决方案:

              namespace sys {
              
              const unsigned one = 1U;
              
              inline bool little_endian()
              {
                  return reinterpret_cast<const char*>(&one) + sizeof(unsigned) - 1;
              }
              
              inline bool big_endian()
              {
                  return !little_endian();
              }
              
              } // sys
              
              int main()
              {
                  if(sys::little_endian())
                      std::cout << "little";
              }
              

              【讨论】:

                【解决方案14】:

                使用 Perl 的单行程序(几乎所有系统都应默认安装):

                perl -e 'use Config; print $Config{byteorder}'
                

                如果输出以 1(最低有效字节)开头,则它是 little-endian 系统。如果输出以更高的数字(最高有效字节)开头,则它是一个大端系统。请参阅Config 模块的文档。

                【讨论】:

                  【解决方案15】:

                  如果您使用的是 .NET:检查 BitConverter.IsLittleEndian 的值。

                  【讨论】:

                    猜你喜欢
                    • 2011-02-06
                    • 2010-09-18
                    • 2011-07-22
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2010-11-03
                    • 2021-06-15
                    • 2010-09-26
                    相关资源
                    最近更新 更多