[Question]
  [
It's not too important anymore, but occasionally [somebody](https://superuser.com/questions/208312/how-to-tell-if-a-windows-computer-has-a-64-bit-cpu-or-os) needs to know.
Here is a simple golf: Taking no user input, tell me if the computer on which the code is run is on a 64-bit operating system, or a 32-bit operating system!
If the code is run on a 32-bit operating system, print "32", if the code is run on a 64 bit operating system, output "64". **Important:** Print any other non-empty string of alphanumeric characters if it's neither 32 or 64 bit.
Please note that a 32 bit program running on a computer with a 64 bit operating system should output "64". You can assume that users will use 64 bit software whenever possible. 
To be eligible for entry, your code must be able to run on ~~Windows 4.10 or newer~~ Microsoft supported Windows systems, and at least one flavor of Linux of your choosing (so long as that flavor is gratis). Compatibility mods can be installed, so long as the program still returns the right value.
The usual [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") rules apply.
Note: If your answer is only meant to print out 32 or 64, but not the alt case, I'll accept it, but it is not a competing answer. 
I'll try and post some results of running these codes on different OSes later!
  
[Answer]
# x86 machine code, 12 bytes
```
8c c8 83 f8 23 b0 20 75 02 00 c0 c3
```
Ungolfed:
```
getKernelBitness:
    mov eax,cs
    cmp eax,0x23 ; 32 bit process on 64 bit kernel has this selector in CS
    mov al,32
    jne kernelIs32Bit
    add al,al    ; return value in eax
kernelIs32Bit:
    ret
```
This function works in Linux when used in ELF32, following i386 SysV ABI, as well as in Windows/Wine when used in PE32, following `stdcall` calling convention.
[Answer]
# x86 Assembly (polyglot), 13 bytes
Bytecode:
```
31 c0 b4 80 48 70 05 04 40 83 e0 60 c3
```
Defines a function which returns 32 if interpreted as 32-bit, 64 if 64-bit, and 32767 if 16-bit.
I wanted to make a polyglot which ran on Windows and Linux, but this is a lot harder than I thought. As it is I'm not sure there's even any way to print a value on non-16-bit Windows without linking.
## Explanation
This code uses two tells to determine the architecture it is running on. The first is the instruction 0x48—on 16 and 32 bits, this is `dec %eax`, but on 64 bits, it is an instruction-size prefix. The second tell is the same instruction, however, when we execute it on the value 0x8000, the most significant bit is flipped only if the register size is 16 bits, setting the overflow flag and letting us use `jo`. 
In 16 bits, this code is interpreted as the following:
```
   0:   31 c0                   xor    %ax,%ax    /* 0x0000 */
   2:   b4 80                   mov    $0x80,%ah  /* 0x8000 */
   4:   48                      dec    %ax        /* 0x7fff */
   5:   70 05                   jo c              /* taken  */
   7:   04 40                   add    $0x40,%al
   9:   83 e0 60                and    $0x60,%ax
   c:   c3                      ret               /* 0x7fff */
```
In 32 bits, this code is interpreted as the following:
```
   0:   31 c0                   xor    %eax,%eax   /* 0x00000000 */
   2:   b4 80                   mov    $0x80,%ah   /* 0x00008000 */
   4:   48                      dec    %eax        /* 0x00007fff */
   5:   70 05                   jo c               /* not taken  */
   7:   04 40                   add    $0x40,%al   /* 0x00007f3f */
   9:   83 e0 60                and    $0x60,%eax  /* 0x00000020 */
   c:   c3                      ret
```
In 64 bits, this code is interpreted as the following:
```
   0:   31 c0                   xor    %eax,%eax   /* 0x00000000 */
   2:   b4 80                   mov    $0x80,%ah   /* 0x00008000 */
   4:   48 70 05                rex.W jo c         /* not taken  */
   7:   04 40                   add    $0x40,%al   /* 0x00008040 */
   9:   83 e0 60                and    $0x60,%eax  /* 0x00000040 */
   c:   c3                      ret
```
[Answer]
# Mathematica, 17 bytes
```
$SystemWordLength
```
[Answer]
## Julia ~~14~~ 13 bytes
```
n->8sizeof(1)
```
Explain:
* Anon function, taking anything (including `nothing`) returning an integer 32, or 64
* Integer literals are of type `Int` which depending if 32 bit or 64 bit, is either an `Int32` or an `Int64` (the `1` could be any digit)
* placing a number before a function call does a juxtaposition multiplication
* This is basically a minified version of the [code for `Sys.WORD_SIZE`](https://github.com/JuliaLang/julia/blob/0b53b9a76fdbfb1358074f99fcdf963a115b79b6/base/sysinfo.jl#L58), used in [rahnema1's answer](https://codegolf.stackexchange.com/a/127327/4397)
Other fun answer is `()->"$(Int)"[4:5]`, but I can't get the count down on that one.
---
-1 thanks to @Roman Gräf
[Answer]
# Boot Loaders
Did you know that GRUB and IPXE both have Turing complete programming languages accessible at run-time? The Syslinux family of boot loaders don't but they can do this.
## IPXE, 36 bytes
```
#!ipxe
cpuid --ext 29 && echo 64 || echo 32
```
the first line is needed if the script is run remotely, but not if typed directly at the command line.
## GRUB, 42 bytes
```
if cpuid -l ; then
echo 64
else
echo 32
fi
```
## Syslinux, 186 bytes
This takes three files the first is syslinux.cfg (or isolinux.cfg, etc.).
```
label a
  kernel ifcpu64.c32
  append s -- t
label s
  kernel menu.c32
  append s.cfg
label t
  kernel menu.c32
  append t.cfg
default a
prompt 0
timeout 0
```
and t.cfg
```
menu title 32
```
ans s.cfg
```
menu title 64
```
For this one the hard part is that syslinux does not have any simple text display capabilities, so the menu is abused.
[Answer]
# julia, ~~20~~ ~~17~~ 16 bytes
```
n->Sys.WORD_SIZE
```
\*Thanks to @LyndonWhite saved 3 bytes
\*Thanks to @RomanGräf saved a byte
Previous answers:
```
()->Sys.WORD_SIZE
print(Sys.WORD_SIZE)
```
[Try it online!](https://tio.run/##yyrNyUw0/f@/oCgzr0QjuLJYL9w/yCU@2DPKVfP/fwA "Julia 0.5 – Try It Online")
[Answer]
## JavaScript (Node.js), 24 bytes
```
_=>process.arch.slice(1)
```
This is a function and returns `'32'`, `'64'`, or if neither `'rm'`.
[Answer]
# C, ~~33~~ ~~31~~ ~~29~~ 23 bytes
```
f(){return sizeof&f*8;}
```
Thanks to commenters @ceilingcat and @Dennis for golfing tips!
[Answer]
## Python 2, 52, 48, 42 41 bytes
```
from struct import*;print calcsize("P")*8
```
Thanks to totallyhuman!
[Answer]
## Java 8, 45 bytes
```
()->System.getProperty("sun.arch.data.model")
```
[Answer]
## PowerShell, 16 bytes
```
8*[IntPtr]::Size
```
Gets the pointer size in bytes, multiplies by 8 to get bits.
[Answer]
# [Perl 6](https://perl6.org), 17 bytes
```
say $*KERNEL.bits
```
[Try it](https://tio.run/##K0gtyjH7/784sVJBRcvbNcjP1UcvKbOk@P9/AA "Perl 6 – Try It Online")
---
There is a related `$?BITS` which contains the number of bits that a native `int` has in the runtime.
```
say $?BITS
```
[Try it](https://tio.run/##K0gtyjH7/784sVJBxd7JMyT4/38A "Perl 6 – Try It Online")
[Answer]
# Windows CMD, 56 52 bytes (thanks Bob!)
```
if EXIST "%ProgramFiles(x86)%" (echo 64)else echo 32
```
Still surprisingly lengthy - longest so far!
[Answer]
# Ruby, 22 bytes
```
p [?a].pack(?p).size*8
```
`["any string"].pack("p")` returns a string whose bytes correspond to the pointer that pointed towards `"any string"`, and is 8 characters if the OS is 64-bit, or 4 characters if the OS is 32-bit.
[Answer]
# C, Win32 API, 103 183 bytes
```
#include <windows.h>
typedef int(WINAPI*F)(HANDLE,int*);b;main(){F f=GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process");return(f!=0&&f(GetCurrentProcess(),&b)&&!b)?32:64;}
```
Actually there are more than 2 cases here. Let's examine them
* The easiest: `IsWow64Process` does not exist: We are on a 32 bit OS
For the next two cases we need to have the knowledge that our binary will be a 32 bit executable. And this description of what will be out into the **out** parameter of `IsWow64Process`
> 
> A pointer to a value that is set to TRUE if the process is running under WOW64. If the process is running under 32-bit Windows, the value is set to FALSE. If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE.
> 
> 
> 
That leaves us with two additional cases:
* `IsWow64Process` exists, and yields TRUE -> We are on a 64 bit machine
* `IsWow64Process` exists, and yields FALSE -> We are on a 32 bit machine
We don't wory about the part where a 64-bit application on a 64-bit Windows yields FALSE. As we *know* that our application is 32-bit 
Oh and there is one additional case that is not covered by this challenge and should be rare anyways:
* IsWow64Process exists, but it fails: We default to 32-bit machine.
This should cover most Windows NT Operating Systems. Have only tested on Win10 64-Bit, Win 7 64-Bit, Win 8.1 32-Bit and WinXP SP1 32-Bit
---
Original answer:
```
#include<windows.h>
main(){return GetProcAddress(GetModuleHandle("Kernel32"),"IsWow64Process")?64:32;}
```
To be sure we need to distinguish only 2 cases
* `IsWow64Process` does not exist in kernel32.dll => We are on a 32 bit machine.
* `IsWow64Process` does exist => We are on a 64 bit machine.
The actual value provided by `IsWow64Process` is irrelevant for this challange, since we want the binary to be 32bit in any case.
Unlike most of the answers, this doesn't rely on the binary itself being compiled on the machine that it's executed on. 
If I knew a shorter function that is present only on 64bit and not 32bit machines, I could shorten the answer.
[Answer]
# C#, 60 50 bytes
```
_=>System.Environment.Is64BitOperatingSystem?64:32
```
Thanks @TheLethalCoder
[Answer]
## R, 16 bytes
```
.Machine[[18]]*8
```
Returns the pointer size.
[Answer]
## Perl, ~~18~~ ~~15~~ 18 bytes
```
say length pack p8
```
[Answer]
# PHP, 18 Bytes
```
<?=PHP_INT_SIZE*8;
```
This correctly handles all of the cases of 32, 64 and other bit CPUs provided that PHP\_INT\_SIZE is correct, it will show the precise size of the CPU no matter what CPU PHP is running on!
If PHP is running on
32-bit OS PHP\_INT\_SIZE == 4,
64-bit OS PHP\_INT\_SIZE == 8,
16-bit OS PHP\_INT\_SIZE == 2 (theoretically)
8-bit OS PHP\_INT\_SIZE == 1 (again theoretically)
128-bit OS PHP\_INT\_SIZE == 16 (Not yet achieved but possible)
[Answer]
# x86 machine code, 8 bytes
```
31 C0 B0 40 48 24 60 C3
```
Ungolfed:
```
31 c0    xor eax,eax
b0 40    mov al, 0x40
48       dec al — in 32-bit mode; "REX.W" in 64-bit mode (ignored)
24 60    and al, 0x60
c3       ret
```
If compiled as a 64-bit executable, it returns 64 in `eax`, and if compiled as 32-bit, then returns 32 — regardless of the OS.
This answer relies on the rules saying:
> 
> You can assume that users will use 64 bit software whenever possible.
> 
> 
> 
[Answer]
**C# (29 bytes)**
```
Console.Write(IntPtr.Size*8);
```
[Answer]
# PowerShell, ~~17~~ 52 bytes
```
try{32+32*((gci \*`))-or(arch)[-1]-eq52)}catch{32}
```
Returns 64 if either of the following is true:
* You have a directory on your current drive with a filename ending in a close paren, the idea being to detect `Program Files (x86)`.
* `arch` returns a string ending in `4` (ASCII 52), like `x86_64`, as opposed to e.g. `i686`.
The try-catch is intended to circumvent the error you get if *gci* returns nothing and you don't have an *arch*. I haven't found a shorter way to do it so far. *gci* is used over *ls* because on Linux, *ls* will produce a visible error.
This version should detect whether the OS is 64-bit rather than just PowerShell, and is tested to work on Windows and Linux. For Mac support, replace `arch` with `uname -m`.
Previous Windows-only version: `-!(ls \*`))*32+64`
[Answer]
# Swift 4 REPL/Playground, 12 bytes
```
Int.bitWidth
```
`Int` is word sized, acting like either `Int32` or `Int64` depending on the system.
[Answer]
# Ruby, 10 bytes
```
p 0.size*8
```
While Ruby can use integers of any length, internally it stores the values that fit in a machine word as `Fixnum`. The method [`Fixnum#size`](https://ruby-doc.org/core-2.2.0/Fixnum.html#method-i-size) always return the length in bytes of a machine word.
The `Fixnum` class was removed in Ruby 2.4.0, its functionality was included in class [`Integer`](http://ruby-doc.org/core-2.4.1/Integer.html). The code stands.
[Answer]
# Shell, 26 bytes
```
uname -m|awk \$0=/_/?64:32
```
[Answer]
# Bash, 25 17 bytes
```
getconf LONG_BIT
```
Thanks to Dennis for golfing help.
[Answer]
# C, 22 bytes
```
f(){return(int**)0+8;}
```
This is a pointer-size based answer that assumes a native binary. The `0` is cast to `int**` (address `0x0`). Then we add 8 to 0, which, in C advances, the pointer by `sizeof(int*)*8`. 4 bytes \* 8 bits = 32, 8 bytes \* 8 bits = 64. So we get `(int**)0x20` and `0x40` which are then implicitly cast as integers by returning them from an implicitly `int`-returning function.
# C, stand-alone, 34 bytes
```
main(){printf("%d\n",(int**)0+8);} 
```
# C, fun with Unicode, 30 code-points, 34 bytes(UTF-8)
```
main(){puts((int**)U" ㈳㐶"+1);}
```
[Answer]
# Java, 50 bytes
```
int b(){return com.sun.jna.Native.POINTER_SIZE*8;}
```
---
[Answer]
# PHP, 29 bytes
```
<?=@php_uname(m)[-1]-4?32:64;
```
<https://3v4l.org/Y6JXv>
[Answer]
# [Python 3](https://docs.python.org/3/), 77 84 71 59 bytes
-13 bytes, thanks to @JonathanAllan!  
Down to 59 by @Clearer
```
from platform import*;print({'4':64,'6':32}[machine()[-1]])
```
[Try it online!](https://tio.run/##K6gsycjPM/7/P60oP1ehICexJC2/KFchM7cgv6hEy7qgKDOvRKNa3UTdysxER91M3crYqDY6NzE5IzMvVUMzWtcwNlbz/38A "Python 3 – Try It Online")
My fist time code-golfing :)  
Should output the correct version even when running 32Bit-Python on 64bit-OS.  
Assuming `platform.machine()` gives `i*86` or `x86` for 32Bit-OS. I don't have one available to check this. Output is `0` when OS is not in 64/32Bit  
Edit: Added print statement, so it got 7 bytes longer 
]