ããªãã®å¥½ããªè¨èªã¯ä½ã§ãããããã¦ãããªãã®å¥½ããªã¢ã«ã´ãªãºã ã¯ä½ã§ããã
好ããªè¨èªãããã¨ããã®è¨èªã§ã©ããªåé¡ã§ã解決ãããã¨ãªããã¡ã«ãªãã¾ãããã®è¨èªã極ããã®ã¯ç´ æ´ããããã¨ã§ããããã®è¨èªãä¼¼ããããªè¨èªã§ããã³ã¼ããæ¸ããªããªã£ãããä»ã®è¨èªã«å¯¾ãã¦è¦åããããªããªã£ã¦ãã¾ãå¯è½æ§ãããã¾ãã
åæ°ãåºãã¦æ°ããè¨èªã«ãã£ã¬ã³ã¸ãã¦ã¿ã¾ãããï¼è²ã ãªè¨èªã«ææ¦ãã¦ã¿ã¾ãããï¼
ä½ããå§ããã°ãããåãããªãã次ã«ã©ã®è¨èªãå¦ã¹ã°ãããåãããªãããã¾ç¹ã«ä½ãå°ã£ã¦ããªããä½ã§ãå¾æãªè¨èªã§æ¸ãã¦ãã¾ãããããã人ãå¤ãã®ã§ã¯ãªãã§ããããã
æ°ããè¨èªã«ãã£ã¬ã³ã¸ãããã£ãããä½ãä¸ã¤ã®æ¹æ³ã¯ãããç¹å®ã®ã¢ã«ã´ãªãºã ãä¸ã¤æ±ºãã¦ãããããè¨èªã§å®è£ ãã¦ã¿ããã¨ã§ãã解ãåé¡ã大ããããã¨åå°½ãã¦ãã¾ãã®ã§ããããã20ã30è¡ç¨åº¦ã§æ¸ããç°¡åãªãã®ãè¯ãã§ãããã大äºãªãã¨ã¯ããã®ã³ã¼ããå®éã«å®è¡ã§ãããã¨ãæå ã§ç¢ºèªãããã¨ã§ããå®è¡å¦çç³»ãå®éã«ã¤ã³ã¹ãã¼ã«ããã³ã¼ããã³ã³ãã¤ã«ãã¦å®è¡ãã¦ã¿ããããã ãã§ãå¤ãã®ãã¨ãå¦ã¶ãã¨ãã§ãã¾ãã
å®éãç§ããããããã£ã¬ã³ã¸ãããã®ã¯ä»åãåãã¦ã§ãããã®ã¨ã³ããªã¼ã§ã¯ãFast inverse squre rootã30ã®è¨èªã§æ¸ãã¦ã¿ãã®ã§ãããããã®ã³ã¼ããç´¹ä»ãããã¨æãã¾ãã
ãªãã以ä¸ã®ã³ã¼ãã¯å ¨ã¦GitHubã«å ¬éãã¦ãã¾ãã
Fast inverse square rootã¢ã«ã´ãªãºã
ã¾ãCè¨èªã«ããå®è£ ãè¦ã¦ã¿ã¾ãããã
#include <stdio.h> #include <stdlib.h> float fastInvSqrt(float x) { int i = *(int*)&x; i = 0x5f3759df - (i >> 1); float y = *(float*)&i; return y * (1.5F - 0.5F * x * y * y); } int main(void) { char *line = NULL, *endptr = NULL; size_t size; float x; while (getline(&line, &size, stdin) != -1) { x = strtof(line, &endptr); if (*endptr == '\n') { printf("%f\n", fastInvSqrt(x)); } } return 0; }
32bitæµ®åå°æ°ç¹æ°ã®å¹³æ¹æ ¹ã®éæ°ã®è¿ä¼¼ãæ±ããã¢ã«ã´ãªãºã ã§ãã
ãããã¯ãã«ãããã®æ¹åã®åä½ãã¯ãã«ãæ±ãã (åè¦ç´ ã®äºä¹åã®å¹³æ¹æ ¹ã®éæ°ãå¿ è¦ã«ãªã) ããã«ããã¤ã¦å®éã«è£½åã§ä½¿ããããã¨ãããããã§ãã ããã¾ã§è¿ä¼¼å¤ã§ã¯ããã¾ãããããã0.3%æªæºã®èª¤å·®ã§æ±ã¾ãã¾ãã
ã¢ã«ã´ãªãºã ã®ãã½ã¯ãfloat
âint
ã®pointer castingã«ããã¾ãã
int i = *(int*)&x; // float x float y = *(float*)&i; // int i
ãã®å¤æã«ãã£ã¦ x
㨠i
(y
㨠i
) ã¯ã©ãããé¢ä¿ã«ããã®ã§ããããã
32bitã®æµ®åå°æ°ç¹æ°ã¯ãä¸ã®bitãã23bitã®ä»®æ°é¨ã¨ã127ã®ã²ã¿ãå±¥ããã8bitã®ææ°é¨ã¨1bitã®ç¬¦å·é¨ããæãã¾ãã å¾ã£ã¦ãæ£ã®32bitæµ®åå°æ°ç¹æ° ã¨ããã®ãããåã32bitã®æ´æ°å¤ã¨ãã¦è§£éããå¤ ã¯ã次ã®è¿ä¼¼å¼ãæãç«ã¡ã¾ãã
ç¹å¥ãªã±ã¼ã¹ã¨ãã¦ã2ã®åªã§ããå ´å (ä»®æ°é¨ = 0) ã¯ãè¿ä¼¼ãªãã«æ¬¡ã®ããã«ãªãã¾ãã
ä¾ãã°ãfloat
ã®16.0ãint
ã«pointer castingãã㨠ã0.125ãint
ã«ãã㨠ã®ããã«ãªãã¾ãã
#include <assert.h> #include <stdio.h> int main(void) { int i, j = 30, passed = 0; float x = (float)(1 << j); while (j >= -30) { i = *(int*)&x; assert(i == ((127 + j) << 23)); x /= 2; j--; passed++; } printf("%d test passed\n", passed); return 0; }
æ±ãããå¤ã ã¨ããã¨ã ã¨ãªãã¾ãã®ã§ã次ã®é¢ä¿å¼ãå¾ããã¾ãã
ããã i = 0x5f3759df - (i >> 1);
ã®è¡ã«å¯¾å¿ãã¾ãã
ãã®å¤ãã¾ãpointer castingã§float
ã«æ»ããã¨ã§ãæåã®è¿ä¼¼å¤ãå¾ããã¾ãã
ããã«ããã¥ã¼ãã³æ³ã®iterationãä¸åè¡ããã¨ã§ç²¾åº¦ãé«ãã¦ãã¾ãã
æ´ã«è©³ãã説æã¯ããããã§ãæç®ã¯ã§ã¦ãã¾ãã®ã§ããã¡ãããåç §ãã ããã https://www.google.com/search?q=Fast+inverse+square+root
ãã¦ãããããè¨èªã§ä¸ã¤ã®ã¢ã«ã´ãªãºã ãæ¸ããã¨ãªã£ãæã«ãç§ã¯ãªããã®ã¢ã«ã´ãªãºã ãé¸ãã ã®ã§ããããã以ä¸ã®çç±ãããããã¾ãã
- ã³ã¼ããå°ãããã大ããããªãããã Hello worldããã ããªããã¥ã¼ããªã¢ã«ã®æåãè¦ãã ãã§çµãã£ã¦ãã¾ããé¢ç½ãããã¾ãããä¸æ¹ã§ãåé¡ãé£ããã¨æ§ã ãªè¨èªã§æ¸ãã¦ããéä¸ã§æ«æãã¦æãåºãã¦ãã¾ãããã§ãã
float
âint
ã®pointer castingãã¢ã«ã´ãªãºã ã®ãã¤ã³ãã§ãããããã©ãå®è£ ããããåãã¦è§¦ãè¨èªã«ããã¦ããã«éãè¦ã¤ãããã¨ããã¨ãããéè¦ã«ãªã£ã¦ãã¾ããpointerããªãè¨èªã§ã¯binary表ç¾ãä»ãã¦å¤æããããã§ããããããããã¥ã¡ã³ããããã¨æ¢ããªãã¨è¦ã¤ããã¾ããããã®å¤æãã¡ããã¨ã§ããªãã¨ããã¡ããã¡ãçãåããã¨ã«ãªãã§ãããã- ãªã«ãããããã®ã¢ã«ã´ãªãºã ã好ãã ãããæµ®åå°æ°ç¹ãã©ã表ããããããå®ã«ãã¾ã使ã£ã¦ãã¾ããæåã«æ°ãã¤ãã人ã¯é ããããªãã¨æãã¾ããããã¦ãä»ãããä½ã®å½¹ã«ãç«ããªãã¨ããåãã«ãå¿æ¹ãããã¨ããã§ãã
- ã»ã¨ãã©ã®è¨èªã«ããã¦ããã®ã¢ã«ã´ãªãºã ãæ¸ãã人éã¯ããããèªåãåãã¦ã§ (ãã¤ãã¼ãªã¢ã«ã´ãªãºã ã ãã¹ã¯ãªããè¨èªã§æ¸ãã¦ãç¡æå³)ãå人æªè¸ã®å°ãå¶è¦ãã¦ããæè¦ã楽ãããç¡æå³ãªãã¨ã¯ãªãã楽ããã
æ¹ãã¦ãåé¡ã®ã¬ã®ã¥ã¬ã¼ã·ã§ã³ãããã°ã©ãã³ã°ã³ã³ãã¹ã風ã«ä¸¦ã¹ã¦ã¿ã¾ãã
- æ£ã®æµ®åå°æ°ç¹ã®æ°ãæ¹è¡åºåãã§ä¸ããããã®ã§ããã®å¹³æ¹æ ¹ã®éæ°ãæ¹è¡åºåãã§åºåããã
- floatâint32ã®Fast inverse square rootã¢ã«ã´ãªãºã ãç¨ãããã¨ã
seq 10000000
ãå ¥åã¨ãã¦ãåä½ãããã¨ã- æ°å¤ã¨ãã¦ä¸æ£ãªå ¥åã¯ç¡è¦ãã¦è¯ãããä¾å¤ãªã©ã§è½ã¡ãªãããã«ãªã£ã¦ããã¨å¥½ã¾ããã
- 許ããã誤差ã¯ãçå¤ã«å¯¾ãã¦0.5%æªæºã¨ããã
ãµã³ãã«å ¥å
100 10 1 0.1 0.01 0.0025
ãµã³ãã«åºå
0.099845 0.315686 0.998307 3.157232 9.982522 19.965044
ãããåé¡è¨å®ãã§ãã¾ããã ä»ã®è¨èªã§ãã®åé¡ã解ãã¨ã©ããªãã®ããéãã楽ãã¿ãªããã覧ãã ããã
C++
#include <iostream> #include <string> float fastInvSqrt(float x) { int i = *reinterpret_cast<int*>(&x); i = 0x5f3759df - (i >> 1); float y = *reinterpret_cast<float*>(&i); return y * (1.5F - 0.5F * x * y * y); } int main() { std::string line; while (std::getline(std::cin, line)) { try { std::cout << fastInvSqrt(std::stof(line, NULL)) << std::endl; } catch (...) {} } return 0; }
C++ã«ã¯4ã¤ã®castæ¼ç®åãããã¾ãããä»åã¯æãå±éºãªcastã§ããreinterpret_cast
ã使ããããå¾ãªãå ´é¢ã§ãã
ã¾ããæååããfloat
ã¸ã®å¤æã«ã¯str::stof
ã使ã£ã¦ã¿ã¾ããã
ãã®é¢æ°ã¯ãå
¥åãæ£ãããªãã¨ä¾å¤ãåãã¾ãã
C#
using System; class FastInvSqrt { public static void Main() { string line; float number; while ((line = Console.ReadLine()) != null) { if (float.TryParse(line, out number)) { Console.WriteLine(fastInvSqrt(number)); } } } unsafe public static float fastInvSqrt(float x) { int i = *(int*)&x; i = 0x5f3759df - (i >> 1); float y = *(float*)&i; return y * (1.5F - 0.5F * x * y * y); } }
Microsoftã«ãã£ã¦éçºããã.NETç³»è¨èªã§ãã
Cã®é¢æ°ã«unsafe
ãã¼ã¯ã¼ããã¤ããã¨ãã®ã¾ã¾åãã¾ããã
float.TryParse
ãå¤æã§ããããä¾å¤ã§ã¯ãªãè¿ãå¤ã§æ±ããã®ã¯ç´ æµã§ãã
åç
§æ¸¡ãã表ãref
ãã¼ã¯ã¼ãããããã¨ããè¨èªã¨ãã¦é¢ç½ãã¨ããã§ãã
Visual Basic
Imports System Imports System.IO Public Class FastInvSqrt Shared Sub Main(args As String()) Dim s As String = Console.ReadLine() Dim x As Single While s IsNot Nothing If Single.TryParse(s, x) Console.WriteLine(fastInvSqrt(x)) End If s = Console.ReadLine() End While End Sub Shared Function fastInvSqrt(x As Single) As Single Dim i As Integer = BitConverter.ToInt32(BitConverter.GetBytes(x), 0) i = &H5f3759df - (i >> 1) Dim y As Single = BitConverter.ToSingle(BitConverter.GetBytes(i), 0) Return y * (1.5 - 0.5 * x * y * y) End Function End Class
.NETç³»è¨èªã§ãã
BitConverterã使ã£ã¦æ°å¤ã®å¤æãè¡ã£ã¦ã¿ã¾ããã
Mainé¢æ°ã¯C#ã¨ã»ã¼åãã§ãã
Dim
ãã¼ã¯ã¼ããEnd Sub
ãªã©ãæãããæãããã¾ãã
16é²æ°è¡¨ç¾ãªãã©ã«ã® &H
ã¨ãã表è¨ã¯ã¦ãã¼ã¯ã§ãã
F#
let fastinvsqrt(x: float32): float32 = let i = System.BitConverter.ToInt32(System.BitConverter.GetBytes(x), 0) let j = 0x5f3759df - (i >>> 1) let y = System.BitConverter.ToSingle(System.BitConverter.GetBytes(j), 0) y * (1.5F - 0.5F * x * y * y) seq { while true do yield stdin.ReadLine() } |> Seq.takeWhile ((<>) null) |> Seq.iter (fun x -> try float32 x |> fastinvsqrt |> printfn "%f" with :? System.FormatException -> ())
.NETã®è¨èªãç¶ãã¾ãã
BitConverterã使ã£ã¦ãããã¨ãªã©ãfastinvsqrt
ã®å®è£
ã¯Visual Basicã¨ã»ã¼åãã§ãã
float
ã64bitã®æµ®åå°æ°ç¹ (=double
) ã表ãã¨ããã®ãå°ãéåæãããã¾ãã
1.5
ã¨æ¸ãã¨float
(=double
) ã«ãªãã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªãã®ã§1.5F
(float32
= single
) ã¨æ¸ãå¿
è¦ãããã¾ãã
ä¾å¤ã®try ... with :?
ããpipe operator (|>
) ãç¹å¾´çã§ãã
Perl
use strict; use warnings; use feature qw(say); while (<>) { say fastInvSqrt($_); } sub fastInvSqrt { my ($x) = @_; my $i = unpack("l", pack("f", $x)); $i = 0x5f3759df - ($i >> 1); my $y = unpack("f", pack("l", $i)); $y * (1.5 - 0.5 * $x * $y * $y); }
æ´å²ã®ããè¨èªã§ãããããã¹ãå¦çãå¾æã§ãä»ãªãwebã¢ããªã±ã¼ã·ã§ã³ã«åºã使ããã¦ãã¾ãã pointerãæ±ããªãè¨èªã§ã¯ãpack/unpackã«ããbinary表ç¾ãä»ãã¦å®è£ ãããã¨ãã§ãã¾ãã å³å¯ã«ã¯pointer castingãã¦ããªãã³ã¼ãã¯Fast inverse square rootã¨è¨ãã¹ãã§ã¯ãªãããããã¾ããããããã§ã¯æ¸ããè¨èªãããªãéããã¦ãã¾ãã¾ãã®ã§ã許ããã ããã
PHP
<?php while ($line = fgets(STDIN)) { echo fastInvSqrt(floatval($line)), "\n"; } function fastInvSqrt($x) { $i = unpack('l', pack('f', $x))[1]; $i = 0x5f3759df - ($i >> 1); $y = unpack('f', pack('l', $i))[1]; return $y * (1.5 - 0.5 * $x * $y * $y); } ?>
webã¢ããªã±ã¼ã·ã§ã³ã«ç¹åããè¨èªã Perlã®ã³ã¼ããç´ããã ãã§ãã ãã©ã¼ãããæå®ãåãã§ãã
Ruby
def fastInvSqrt(x) i = [x].pack("e").unpack("i")[0] i = 0x5f3759df - (i >> 1) y = [i].pack("i").unpack("e")[0] y * (1.5 - 0.5 * x * y * y) end if __FILE__ == $0 STDIN.each_line do |line| p fastInvSqrt(line.to_f) end end
ãªãã¸ã§ã¯ãæåã®è¨èªã§ãwebã¢ããªã±ã¼ã·ã§ã³ãã¬ã¼ã ã¯ã¼ã¯Ruby on Railsãä¸å¿ã¨ãã¦åºã使ããã¦ãã¾ãã
Perlè²ãã®pack/unpackã使ããã®ã§ãå°ãæ¸ãç´ãã ãã§åãã¾ããã
ä¸è¡ãã¤å¦çã§ããSTDIN.each_line
ãç´ æµã§ãã
Python
import struct import sys def fastInvSqrt(x): i = struct.unpack('>i', struct.pack('>f', x))[0] i = 0x5f3759df - (i >> 1); y = struct.unpack('>f', struct.pack('>i', i))[0] return y * (1.5 - 0.5 * x * y * y) if __name__ == '__main__': for line in iter(sys.stdin.readline, ""): print(fastInvSqrt(float(line)))
webã¢ããªã±ã¼ã·ã§ã³ããæ°å¼å¦çãæ©æ¢°å¦ç¿ã¾ã§å¹
åºã使ç¨ããã¦ããè¨èªã
ãã¯ãpack/unpackãããã®ã§ãbinary表ç¾ãä»ãã¦å¤æãã¾ããã
ãã©ã¼ãããæåã«çç®ããã¨ãä¸æåç®ã®>
ã<
(ä»ã« @
, =
, !
) ãªã©ã«ããendianãæå®ããæ¹æ³ã¯ãä¸ã®3ã¤ã®è¨èªã¯ç°ãªã£ã¦ãã¾ãã
R
fastInvSqrt <- function(x) { i <- readBin(writeBin(as.numeric(x), raw(), size=4), integer(), size=4) i <- 0x5f3759df - bitwShiftR(i, 1) y <- readBin(writeBin(as.integer(i), raw(), size=4), double(), size=4) y * (1.5 - 0.5 * x * y * y) } f <- file("stdin") open(f) while (length(line <- readLines(f, n=1)) > 0) { write(fastInvSqrt(as.numeric(line)), stdout()) }
çµ±è¨å¦çã«åºãç¨ãããã¦ããè¨èªã§ãã
ãã¤ã³ã¿ãããã¾ããããæµ®åå°æ°ç¹åã«32bitã¨64bitã®åºå¥ããªãã®ã§è¦å´ãã¾ãã
readBin
ã«double, size=4
ãæå®ããã¨32bitã®æ°å¤ã¨ãã¦èªã¿è¾¼ãã§ããã¾ãã
ä»ã®ã·ã¹ãã ãåãããã¼ã¿ãã¡ã¤ã«ãèªã¿è¾¼ãã¨ããéè¦ã¯ããããã§ããããã
主ã«ãã¡ã¤ã«ã¨ã®ããåãã«ä½¿ãé¢æ°ã§ãããraw vectorãå¼æ°ã«åããã¨ãã§ãã¾ãã
JavaScript
require('readline').createInterface({ input: process.stdin, output: process.null }).on('line', function(line) { console.log(fastInvSqrt(parseFloat(line))); }); function fastInvSqrt(x) { var i = floatToUInt32(x); i = 0x5f3759df - (i >> 1); var y = uint32ToFloat(i); return y * (1.5 - 0.5 * x * y * y); } function floatToUInt32(x) { var buf = new ArrayBuffer(4); new Float32Array(buf)[0] = x; return new Uint32Array(buf)[0]; } function uint32ToFloat(i) { var buf = new ArrayBuffer(4); new Uint32Array(buf)[0] = i; return new Float32Array(buf)[0]; }
ãã©ã¦ã¶ã¼ã§åããã¨ã¯ãã¡ãããJavaScriptãCSSã¸ã®ãã©ã³ã¹ãã¤ã©ãJavaScriptã§æ¸ããã¦ãããã¨ããããwebéçºã«ã¯æ¬ ãããªãè¨èªã
pointerãªã©ãã¡ãããªããã¾ãæ°å¤ã«floatã¨doubleã®åºå¥ã¯ããããæ´æ°åã¨æµ®åå°æ°ç¹åã®åºå¥ããªããRãããããã«ä¸å©ãªç¶æ³ã§ãã
TypedArrayããã¾ã使ãã¨ãªãã¨ãå®è£
ãããã¨ãã§ãã¾ããã
ArrayBuffer
ãå¼æ°ã«ãã¦Uint32Array
ãFloat32Array
ãä½ããã®ããã¤ã³ãã§ãã
CoffeeScript
require 'readline' .createInterface input: process.stdin output: process.null .on 'line', (line) => console.log fastInvSqrt parseFloat line fastInvSqrt = (x) -> i = floatToUInt32 x i = 0x5f3759df - (i >> 1) y = uint32ToFloat i y * (1.5 - 0.5 * x * y * y) floatToUInt32 = (x) -> buf = new ArrayBuffer 4 (new Float32Array(buf))[0] = x new Uint32Array(buf)[0] uint32ToFloat = (i) -> buf = new ArrayBuffer 4 (new Uint32Array(buf))[0] = i new Float32Array(buf)[0]
JavaScriptã«å¤æãããAltJSã®ä¸ã¤ã§ãJavaScriptèªä½ã®æ§æã«ã大ããªå½±é¿ãä¸ãã¾ããã
ä¸ã®JavaScriptã®ã³ã¼ããåãããããã«æ¸ãã ãã§ãã
(new Float32Array(buf))[0] = x
ã new Float32Array(buf)[0] = x
ã¨æ¸ããªãã®ã¯æ®å¿µãªã¨ããã§ãã
LiveScript
require \readline .createInterface do input: process.stdin output: process.null .on \line, (line) -> line |> parseFloat |> fastInvSqrt |> console.log fastInvSqrt = (x) -> i = floatToUInt32 x i = 0x5f3759df - (i .>>. 1) y = uint32ToFloat i y * (1.5 - 0.5 * x * y * y) floatToUInt32 = (x) -> buf = new ArrayBuffer 4 (new Float32Array buf).0 = x (new Uint32Array buf).0 uint32ToFloat = (i) -> buf = new ArrayBuffer 4 (new Uint32Array buf).0 = i (new Float32Array buf).0
CoffeeScriptã¨ããä¼¼ã¦ããAltJSã§ãããããã«å
é²çãªæ©è½ãå
¥ã£ã¦ãã¾ãã
ããã¯ã¹ã©ãã·ã¥ããå§ã¾ãåèªãæååã«ãªã£ãããã (\line == 'line'
) ã®ã¯ãä»ã®è¨èªã§ã¯è¦ããã¨ããªãsyntaxã§ã (ããã¦è¨ãã°Rubyã®symbolã«ä¼¼ã¦ãã¾ã)ã
pipe operator |>
ã composition operator >>
ãªã©ãF#ã«å¤§ããªå½±é¿ãåãã¦ãããã¨ãåããã¾ãã
>>
ãé¢æ°åæãªã®ã§ãã·ããæ¼ç®åã.>>.
ã«ãªã£ã¦ãã¾ãã
PureScript
module Main where import Prelude import Control.Monad.Eff (Eff) import Control.Monad.Eff.Console (CONSOLE, logShow) import Control.Monad.Eff.Exception (EXCEPTION) import Data.ArrayBuffer.ArrayBuffer (create) import Data.ArrayBuffer.DataView (READER, WRITER, whole, getInt32, getFloat32, setInt32, setFloat32) import Data.Int.Bits (shr) import Data.Maybe (fromJust) import Data.Monoid (mempty) import Global (readFloat) import Node.Process (stdin) import Node.ReadLine (READLINE, setLineHandler, createInterface) import Partial.Unsafe (unsafePartial) main :: forall e. Eff (console :: CONSOLE, readline :: READLINE, err :: EXCEPTION, reader :: READER, writer :: WRITER | e) Unit main = do interface <- createInterface stdin mempty setLineHandler interface $ \line -> logShow =<< fastInvSqrt (readFloat line) fastInvSqrt :: forall e. Number -> Eff (reader :: READER, writer :: WRITER | e) Number fastInvSqrt x = do i <- floatToUInt32 x let j = 0x5f3759df - unsafePartial i `shr` 1 y <- uint32ToFloat j pure $ y * (1.5 - 0.5 * x * y * y) floatToUInt32 :: forall e. Number -> Eff (reader :: READER, writer :: WRITER | e) Int floatToUInt32 x = do let dataView = whole $ create 4 setFloat32 dataView x 0 unsafePartial $ map fromJust $ getInt32 dataView 0 uint32ToFloat :: forall e. Int -> Eff (reader :: READER, writer :: WRITER | e) Number uint32ToFloat i = do let dataView = whole $ create 4 setInt32 dataView i 0 unsafePartial $ map fromJust $ getFloat32 dataView 0
Haskellã«ä¼¼ãsyntaxãæã¤AltJSã§ãã JavaScriptã«ã³ã³ãã¤ã«ãããè¨èªã§ãã®ã§ãåºæ¬çã«ã¯JavaScriptã®ã³ã¼ããç´ãã ããªã®ã§ãããHaskellã®çµé¨ããªãã¨é£ããã§ãããã Eff monadã®åå®ç¾©ãPartial type classãªã©ãHaskellã¨ç°ãªãã¨ãããå¤ãããã¾ãã
J
fastInvSqrt =: 3 : 0 i =. _2 ic 1 fc y i =. (dfh'5f3759df') - _1 (33 b.) i z =. _1 fc 2 ic i z * (1.5 - 0.5 * y * z * z) ) echo & fastInvSqrt & (0 & ".) & (-. & CRLF) ;. 2 &. stdin '' exit ''
æ¸ãã®ãèªãã®ãé£ããè¨èªã§ãããæ°æ¥ã»ã©å®¶ã«ç± ãã£ã¦ããã¥ã¡ã³ããèªã¿ããã°ãããªãã«åããããã«ãªãã¾ã (Vocabularyãã¨ã¦ã便å©)ã
é¢æ°ã§ã¯ãªãåè©ã¨è¡¨ç¾ããããåè©ã®æåãå¤ããé¢æ°ãå¯è©ã¨è¡¨ç¾ãããããè¨ãåãã¯ããªãã¦ãã¼ã¯ã
æ¼ç®åã常ã«å³çµåã ã£ãããic =: 3!:4
ãfc =: 3!:5
ãªã©ã«ããæ°åã¨binaryåã®å¤æãdfh
ã«ãã16é²æ°è¡¨ç¾ã®å¤æã0 ". y
ã«ããæååããæ°åã¸ã®å¤æã3 : 0
ã«ããåè©ã®å®ç¾©ãªã©ãä¸ã®ãã£ãæ°è¡ã®ã³ã¼ããæ¸ããããã«ãªãã¾ã§ã«å¦ã°ãªããã°ãªããªããã¨ã¯å¤ãã
Go
package main import ( "bufio" "fmt" "os" "strconv" "unsafe" ) func fastInvSqrt(x float32) float32 { i := *(*int32)(unsafe.Pointer(&x)) i = 0x5f3759df - i>>1 y := *(*float32)(unsafe.Pointer(&i)) return y * (1.5 - 0.5*x*y*y) } func main() { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { if x, err := strconv.ParseFloat(scanner.Text(), 32); err == nil { fmt.Println(fastInvSqrt(float32(x))) } } }
Googleãéçºããã³ã³ãã¤ã«è¨èªã§ãã
ããã¾ã§ãã°ããã¹ã¯ãªããè¨èªãç¶ãã¦ãã¾ããããããããã³ã³ãã¤ã«è¨èªãç¶ãã¾ãã
æ®éã«pointer castingã§ããã ãã§å®å¿æãåºã¦ãã¾ããã
unsafe.Pointer
ã¨ããåé¢ã¯ãããã«ãå±éºãªãã¨ããã£ã¦ãããã ã¨ãããã¨ãåèµ·ãã¦ããã¾ãã
strconv.ParseFloat
ã®è¿ãå¤ã®æ±ãã«ãè¦ãããããã«ãã¨ã©ã¼ã¯ä¾å¤ã§ã¯ãªãè¤æ°è¿ãå¤ã§æ±ãã®ãæ
£ç¿ã¨ãªã£ã¦ãã¾ãã
æ¨æºã®ã³ã¼ããã©ã¼ããã¿ã¼gofmt
ã§ã³ã¼ããæ´å½¢ããæ
£ç¿ããããæåã§ãã
Swift
func fastInvSqrt(x: Float) -> Float { var z: Float = x var i: Int = UnsafeMutablePointer<Int>(withUnsafeMutablePointer(&z, { $0 })).memory i = 0x5f3759df - (i >> 1) let y: Float = UnsafeMutablePointer<Float>(withUnsafeMutablePointer(&i, { $0 })).memory return y * (1.5 - 0.5 * x * y * y) } while let line = readLine() { if let x = Float(line) { print(fastInvSqrt(x)) } }
AppleãéçºããWWDC 2014ã§çºè¡¨ãããè¨èªã§ãã
æ®éã¯ãããªå±ãªã£ãããã³ã¼ãæ¸ããªãã§ããããã©ãä½ã¬ã¤ã¤ã¼ã¨ã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãç¨æããã¦ããããã¤ã³ã¿ã«ã¢ã¯ã»ã¹ãããã¨ãã§ãã¾ã (ããããã¾ãã)ã
if let
ãwhile let
ãªã©ãoptional bindingã¯ç´ æµã ã¨æãã¾ãã
å¤æ° var
ã¨å®æ° let
ã¯åºå¥ããã¾ãã
Rust
use std::io::BufRead; fn fast_inv_sqrt(x: f32) -> f32 { let i = unsafe { *std::mem::transmute::<&f32, &i32>(&x) }; let j = 0x5f3759df - (i >> 1); let y = unsafe { *std::mem::transmute::<&i32, &f32>(&j) }; y * (1.5 - 0.5 * x * y * y) } fn main() { let stdin = std::io::stdin(); for line in stdin.lock().lines().filter_map(|x| x.ok()) { match line.parse::<f32>() { Ok(x) => println!("{}", fast_inv_sqrt(x)), Err(_) => {}, } } }
Mozillaã«ããéçºããã¦ããè¨èªã§ãã
std::mem::transmute
ã¨ããé¢æ°ã«ãããpointer castingãè¡ããã¨ãã§ãã¾ãã
unsafe
ãã¼ã¯ã¼ãã¯C#ã«å°ãä¼¼ã¦ãã¾ãã
å±éºãªãã¨ããã¦ããæããããã§ã¦ãã¾ãã
D
import std.conv; import std.stdio; import std.string; void main() { foreach (line; stdin.byLine()) { try { writeln(fastInvSqrt(to!float(chomp(line)))); } catch (ConvException e) {} } } float fastInvSqrt(float x) { int i = *cast(int*)(&x); i = 0x5f3759df - (i >> 1); float y = *cast(float*)(&i); return y * (1.5F - 0.5F * x * y * y); }
赤ãDã®æåã®å½¢ããããã£ã©ã¯ã¿ã¼ãç¹å¾´çãªã³ã³ãã¤ã«è¨èªã§ãã 綺éºãªC/C++ã¨ããå°è±¡ã§ãã ä¸ã®ã³ã¼ãã§ã¯åãç«ã¦ã¦ç¹å¾´ãªã¨ããã¯ããã¾ããã
Crystal
def fastinvsqrt(x : Float32) : Float32 i = pointerof(x).as(Int32*).value i = 0x5f3759df - (i >> 1) y = pointerof(i).as(Float32*).value y * (1.5 - 0.5 * x * y * y) end while line = gets puts fastinvsqrt(line.to_f32) end
Rubyã«ä¼¼ãæ§æãæã¤ãéçåä»ãã®ã³ã³ãã¤ã«è¨èªã§ãã
Cè¨èªã¨ã®éç¨ãèæ
®ããã¦ãã¦ãpointerãæ±ãã¤ã³ã¿ã¼ãã§ã¼ã¹ãç¨æããã¦ãã¾ãã
ãã®syntaxã¯ä»ã®è¨èªã§ã¯ãã¾ãè¦ããã¾ããããç§ã¯ããªã好ãã§ããã
Cè¨èªé¢¨ã®&
ãã*
ãããèªã¿ãããæ°ãããã®ã§ãããã©ãã§ããããã
ã³ã¼ãå
¨ä½ãå¼ãç· ã¾ã£ã¦ãã¦ã·ã³ãã«ã§ãã
ã³ã³ãã¤ã«è¨èªã§ãå®è¡æã®ããã©ã¼ãã³ã¹ãåªç§ã§ãã
Nim
import strutils proc fastInvSqrt(x: float32): float32 = let i = cast[int32](x) let j = 0x5f3759df - i shr 1 let y = cast[float32](j) return y * (1.5 - 0.5 * x * y * y) while true: try: let input = stdin.readLine try: echo fastInvSqrt(parseFloat(input)) except ValueError: continue except IOError: break
ãã¡ãã¯Pythonã«ä¼¼ãæ§æãæã¤ãéçåä»ãã®è¨èªã§ãã
ãã®è¨èªãCrystalåæ§ãããã¨ä½ã¬ã¤ã¤ã¼ã触ããè¨èªã§ãã
bit patternãä¿åããtype castã¯cast[T](v)
ã®ããã«ã¨ã¦ããã£ãããã¦ãã¾ãã
ããã¦pointerã§ã®castã§ãããã¨ã強調ããããã«ãlet i = cast[ptr int32](addr(z))[]
ã¨æ¸ããã¨ãã§ãã¾ãã
addr
ãåããã®ã¯å¤æ´å¯è½ãªå¤æ°ã ãã¨ããã®ã¯Swiftã«ä¼¼ã¦ãã¾ãã
pointer dereferenceãptr[]
ãªã®ã¯ä»ã§ã¯è¦ããã¨ãããã¾ãã (Cã§ã¯ *ptr
) ããé
åã¨ä¼¼ã¦ãã¦ãã¡ãã®ã»ããä¸è²«æ§ãããããã«æãã¦ãã¾ãã
Crystalã¨åæ§ãå®è¡æããã©ã¼ãã³ã¹ã¯åªç§ã§ãã
Java
import java.util.Scanner; public class FastInvSqrt { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { try { float x = Float.parseFloat(scanner.nextLine()); System.out.printf("%f\n", fastInvSqrt(x)); } catch (NumberFormatException e) {} } } public static float fastInvSqrt(float x) { int i = Float.floatToRawIntBits(x); float y = Float.intBitsToFloat(0x5f3759df - (i >> 1)); return y * (1.5F - 0.5F * x * y * y); } }
æ¥åç³»ãwebã¢ããªã±ã¼ã·ã§ã³ãã¹ããã¢ããªéçºãªã©ãåºã使ããã¦ãããªãã¸ã§ã¯ãæåã®è¨èªã§ãã
çã®pointerã¯ããã¾ããããæ¨æºã©ã¤ãã©ãªã®é¢æ°ã§floatã¨intãå¤æããé¢æ°ãããã®ã§ãããç¨ãããã¨ãã§ãã¾ãã
æååããfloatã¸ã®å¤æé¢æ°Float.parseFloat
ãä¾å¤NumberFormatException
ãæããã®ã§ããããcatchããå¿
è¦ãããã¾ãã
Groovy
Scanner scanner = new Scanner(System.in) while (scanner.hasNext()) { try { println fastInvSqrt(Float.parseFloat(scanner.nextLine())) } catch (NumberFormatException e) {} } def fastInvSqrt(float x) { int i = Float.floatToRawIntBits(x) float y = Float.intBitsToFloat(0x5f3759df - (i >> 1)) y * (1.5F - 0.5F * x * y * y) }
JVMä¸ã®è¨èªã§Javaã¨è¦ªåæ§ãé«ãè¨èªã ä¸è¨ã®ã³ã¼ããJavaã®ã³ã¼ãããã£ãããã®ã¾ã¾æã£ã¦ãããã®ã§ãã ã»ãã³ãã³ãreturnãæ¸ããªãã¦ããã¦ãã£ãããã¦ãã¾ãã
Kotlin
fun main(args: Array<String>) { while (true) { val line = readLine() if (line == null) break try { println(fastInvSqrt(line.toFloat())) } catch (e: NumberFormatException) {} } } fun fastInvSqrt(x: Float): Float { val i = java.lang.Float.floatToRawIntBits(x) val y = java.lang.Float.intBitsToFloat(0x5f3759df - (i shr 1)) return y * (1.5F - 0.5F * x * y * y) }
ããã¾ãJVMä¸ã§å®è£
ããã¦ãã¦ãJavaã¨ã®ç¸äºéç¨ãå¯è½ãªè¨èªã§ãã
å³ãããã·ãããshr
ä¸ç½®æ¼ç®åãªã®ãã¦ãã¼ã¯ã§ãã
nullã®æ±ããSwiftã¨ä¼¼ã¦ãã¾ãã
Scala
object FastInvSqrt { def main(args: Array[String]) { Iterator.continually(scala.io.StdIn.readLine()).takeWhile(_ != null).foreach { line => util.control.Exception.catching(classOf[NumberFormatException]) opt line.toFloat map { x => println(fastInvSqrt(x)) } } } def fastInvSqrt(x: Float): Float = { val i = java.lang.Float.floatToRawIntBits(x) val y = java.lang.Float.intBitsToFloat(0x5f3759df - (i >> 1)) y * (1.5F - 0.5F * x * y * y) } }
åããJVMä¸ã®è¨èªã§ãã
ä¸è¨ã®JVMç³»ã®è¨èªã¨åæ§ã§ãããString#toFloat
ãä¾å¤ãæããã®ã§ããããcatchããå¿
è¦ãããã¾ãã
ã»ãã³ãã³ãreturn
ãä¸è¦ã§ãã
val
ã¨var
ãããã¾ã (ä»ã«Kotlin, Swift, Rust, Nimãªã©ããã®ç¹å¾´ãæã¡ã¾ã)ã
Clojure
(defn fast-inv-sqrt [x] (let [i (Float/floatToRawIntBits x) y (Float/intBitsToFloat (- 0x5f3759df (bit-shift-right i 1)))] (* y (- 1.5 (* 0.5 x y y))))) (doseq [line (line-seq (java.io.BufferedReader. *in*))] (try (println (fast-inv-sqrt (read-string line))) (catch java.lang.RuntimeException e ())))
JVMè¨èªç¹ããã§ãClojureã§ãã Javaã§æ¸ããã°Clojureã§æ¸ãã®ãç°¡åã§ãã LISPç³»ã§ããletãdefnãããã®æ¬å¼§ã®æ°ãå°ãªããã³ã¼ãã¯ãã£ãããã¦ãã¾ãã
OCaml
let fast_inv_sqrt x = let i = Int32.bits_of_float x in let j = Int32.sub (Int32.of_int 0x5f3759df) (Int32.shift_right i 1) in let y = Int32.float_of_bits j in y *. (1.5 -. 0.5 *. x *. y *. y) let () = try while true do let line = input_line stdin in try let x = float_of_string line in Printf.printf "%f\n%!" (fast_inv_sqrt x) with Failure _ -> () done; with End_of_file -> ()
float
ã¯64bitã®æ°åã§ãããInt32.bits_of_float
ã32bitã§ã®binary表ç¾ã«ãããã®ãint32
ã§è¿ãã¦ããã¾ãã
float
ä¸ã®æ¼ç®åã¯-.
*.
ã¨ãªã£ã¦ãããint
ä¸ã®æ¼ç®åã¨ã¯åºå¥ããã¦ãã¾ãã
printf
ã®%!
ã§fflushããã®ã¯ãä»ã®è¨èªã§ã¯ãã¾ãè¦ãªãç¹å¾´ã§ãã
Haskell
import Control.Monad ((<=<)) import Data.Bits (shiftR) import Data.Traversable (mapM) import Data.Word (Word32) import Foreign.Marshal.Alloc (alloca) import Foreign.Ptr (castPtr) import Foreign.Storable (peek, poke) import Prelude hiding (mapM) import Text.Read (readMaybe) main :: IO () main = mapM_ (mapM (print <=< fastInvSqrt) . readMaybe) . lines =<< getContents fastInvSqrt :: Float -> IO Float fastInvSqrt x = alloca $ \ptr -> do poke ptr x i <- peek (castPtr ptr) poke (castPtr ptr) $ 0x5f3759df - (i :: Word32) `shiftR` 1 y <- peek ptr return $ y * (1.5 - 0.5 * x * y * y)
é
延è©ä¾¡ãç¹å¾´çãªç´ç²é¢æ°åè¨èªã§ãã
ã¡ã¢ãªã¼é åãç¨æãã¦ãããã«æ¸ãè¾¼ãã§(poke)ãå¥ã®åã§èªã¿åã(peek)ã¨ããçºæ³ãå¿
è¦ã§ãã
Float -> Word32
ã¨ãã®éã§äºåã®å¤æãå¿
è¦ã§ããããµã¤ãºãåããªã®ã§åãã¡ã¢ãªã¼é åã使ãåããã¨ãã§ãã¾ãã
getContents
ãã¦lines
ã§åå²ãã¦ããããã®è¡ã⦠ã¨æ¸ããã³ã¼ãã巨大ãªå
¥åã«ãã¯ã©ãã·ã¥ããªãã®ã¯é
延è©ä¾¡ã®ãããã§ãã
Erlang
-module(fastinvsqrt). -export([main/0, fast_inv_sqrt/1]). main() -> case io:get_line("") of eof -> ok; {error, _} -> ok; Line -> catch io:format("~f~n", [fast_inv_sqrt(parse_float(Line))]), main() end. fast_inv_sqrt(X) -> <<I:32/integer>> = <<X:32/float>>, J = 16#5f3759df - (I bsr 1), <<Y:32/float>> = <<J:32/integer>>, Y * (1.5 - 0.5 * X * Y * Y). parse_float(Str) -> case string:to_float(Str) of {error, _} -> case string:to_integer(Str) of {error, _} -> error; {Int, _} -> float(Int) end; {Float, _} -> Float end.
並è¡å¦çãéè¦ããåçåä»ãã®é¢æ°åè¨èªã§ãã
ãã®ã¨ã³ããªã¼ã®ã³ã¼ãã®ä¸ã§ãåããæã®åã³ãæã大ããã£ãã³ã¼ãã§ãã
<< ... >>
ã¯ãã¤ããªã¼åã表ãã¾ãã
ãã¤ããªã¼åã®ãã¿ã¼ã³ãããã«ããfloat
ã¨interger
ã¨ã®å¤æãè¡ã£ã¦ãã¾ãã
16é²æ°è¡¨ç¾ãªãã©ã«ã®16#
ã¨ãã表è¨ãio:format
ã®ãã©ã¼ãããæå®~f~n
ããããã·ããã®bsr
ãªã©ã¯ã¦ãã¼ã¯ã§ãã
string:to_float("100")
ãã¨ã©ã¼ãè¿ãã®ãæ®å¿µã§ã (ããæ¹æ³ãããã°æãã¦ãã ãã)ã
ã«ã³ããã»ãã³ãã³ãããããªã©ãæåã¯é£ããã
Elixir
defmodule Main do def main() do case IO.gets "" do :eof -> :ok {:error, _} -> :ok line -> case Float.parse(line) do :error -> :ok {float, _} -> IO.puts FastInvSqrt.fast_inv_sqrt(float) end main() end end end defmodule FastInvSqrt do use Bitwise, only_operators: true def fast_inv_sqrt(x) do <<i::size(32)-integer>> = <<x::float-32>> j = 0x5f3759df - (i >>> 1) <<y::float-32>> = <<j::size(32)-integer>> y * (1.5 - 0.5 * x * y * y) end end
Erlangã®ä»®æ³ç°å¢ä¸ã§åä½ããè¨èªãElixirã
Erlangã®ã³ã¼ãã¨ã»ã¼åãã
ãããã·ããã¯>>>
ãªã®ã¯ã>>
ããã¤ããªã¼åã®éãæ¬å¼§ã§æ¢ã«ä½¿ããã¦ããããã§ããããã
syntaxã¯Rubyã«ä¼¼ã¦ãã¾ãããErlangããå¦ã°ãªãã¨æ¸ãã«ããã
Scheme
(use binary.pack) (define (main args) (define (main-loop) (let ((line (read-line))) (cond ((not (eof-object? line)) (let ((x (string->number line))) (cond ((not (eqv? x #f)) (display (fast-inv-sqrt (* 1.0 x))) (newline)))) (main-loop))))) (main-loop) 0) (define (fast-inv-sqrt x) (let* ((i (car (unpack "l" :from-string (pack "f" (list x) :to-string? #t)))) (i (- #x5f3759df (ash i -1))) (y (car (unpack "f" :from-string (pack "l" (list i) :to-string? #t))))) (* y (- 1.5 (* 0.5 x y y)))))
LISPç³»ã®è¨èªã®ä¸ã¤ã§ãã æ´å²ãé·ãç»å ´ããã®ã¯1975å¹´ã§ãããä»ã§ãæè²ã®ç¾å ´ã§ä½¿ããã¦ãã¾ãã ç§ã大å¦æ代ã«è§¦ã£ãã®ãæãåºãã¾ããã binary.packã©ã¤ãã©ãªã¼ããã£ã¦å©ããã¾ããã
Assembly
ãã¦ããã£ããããã¾ã§æ§ã
ãªè¨èªã§æ¸ãã¦ããããã§ããã以ä¸ã®ã³ã¼ãã¯å¹³æ¹æ ¹ã®éæ°ãé«éã«æ±ããã¨ããç®çã«ããã¦ããã¯ãæå³ãããã¾ããã
X86ã®å½ä»¤ã«rsqrtss
ã¨ãããã¾ãã«å®è£
ããããã¨ãã®ã¾ã¾ã®å½ä»¤ããããä¸è¨ã®ããããã³ã¼ããããéã (ã¯ãã ) ããã§ãã
fmt0: .string "%f" fmt1: .string "%f\n" .globl main main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $32, %esp jmp .L4 .L5: movl 28(%esp), %eax movl %eax, (%esp) call fastInvSqrt fstpl 4(%esp) movl $fmt1, (%esp) call printf .L4: leal 28(%esp), %eax movl %eax, 4(%esp) movl $fmt0, (%esp) call __isoc99_scanf cmpl $-1, %eax jne .L5 movl $0, %eax leave ret fastInvSqrt: pushl %ebp movl %esp, %ebp subl $8, %esp movd 8(%ebp), %xmm0 rsqrtps %xmm0, %xmm0 movd %xmm0, -4(%ebp) flds -4(%ebp) leave ret
ç§ã¯ã¢ã»ã³ããªãæ¸ãã®ã¯æ
£ãã¦ããããCè¨èªã®ã³ã¼ããgcc -S
ããã³ã¼ããå
ã«æ¸ãã¦ã¿ãã®ã§å¤ãªã¨ãããããããããã¾ããã
ãã 注ç®ãã¦æ¬²ããã®ã¯ãã®ä¸è¡ã§ãã
rsqrtps %xmm0, %xmm0
ãã®ä¸å½ä»¤ã«ãã£ã¦å¹³æ¹æ ¹ã®éæ°ã®è¿ä¼¼å¤ãæ±ãã¦ãã¾ãã æ¶æ¸¬ã«éãã¾ããããéããåè² ã®ã²ã¼ã ã¨ã³ã¸ã³ã®å®è£ ã§ã¯ããã®å½ä»¤ã¸ã®æé©åã使ããã¦ãããã¨ã§ãããã
ã¡ãªã¿ã«Cã§ã®å®è£
ãgcc -S
ãããã®ã¯æ¬¡ã®ãããªæãã§ããã
f0: .float 0.5 f1: .float 1.5 fastInvSqrt: pushl %ebp movl %esp, %ebp subl $16, %esp leal 8(%ebp), %eax movl (%eax), %eax sarl %eax movl %eax, %edx movl $1597463007, %eax subl %edx, %eax movl %eax, -8(%ebp) leal -8(%ebp), %eax movl (%eax), %eax movl %eax, -4(%ebp) flds 8(%ebp) flds f0 fmulp %st, %st(1) fmuls -4(%ebp) fmuls -4(%ebp) flds f1 fsubp %st, %st(1) fmuls -4(%ebp) leave ret
leal
ãã¦movl
ãã¦ããã¨ãããé¢ç½ãã¨ããã§ãã
ã¾ã¨ã
30åã®ããã°ã©ãã³ã°è¨èªã§Fast inverse square rootã¨ããã¢ã«ã´ãªãºã ãå®è£ ãã¦ã¿ã¾ããã ã³ã¼ãã¯å ¨ã¦ä»¥ä¸ã®ãªãã¸ããªããcloneã§ãã¾ãã ãã®è¨èªããªããããªããï¼ã¨ãããããã³ããããããã§ããã許ãã¦ãã ããã SmalltalkãLua, Cleanãªã©ã¯æ¸ããã¨ãã¾ããããfloatâint32ã®å¤æãã©ãããã°ãããåããã¾ããã§ããã AdaãDelphi, Hexe, Io, Miranda, Tcl, Racket, Pony, Forthãªã©ãã¾ã ã¾ã æ¸ãããè¨èªã¯æ®ã£ã¦ããã®ã§ãæéãããã¨ãã«æ¸ãã¦ãããã¨æãã¾ãã
èªåãæ¸ãããã¨ããªãè¨èªã®å¦çç³»ãã¤ã³ã¹ãã¼ã«ããç®çã®ã¢ã«ã´ãªãºã ãããã«éãå®è£ ãããã¨ããã®ã¯ãããªããã¹ãã¼ãã®ããã§ãã ãã®ã¨ã³ããªã¼ã®ããã«è²ã 調ã¹ã¦ããããæåã®Cã®å®è£ ãæ¸ãã¦ããäºãæãããããã£ã¦ãã¾ãã¾ããã åç´ã«30ã§å²ãã¨2æ¥ã«1è¨èªã§ãããä¸æéã»ã©ã§æ¸ãããã®ãããã°ãæ°æ¥éããã¥ã¡ã³ããèªã¾ãªãã¨æ¸ããªããã®ãããã¾ããã é·ãå¤ç¬ãªæ¦ãã§ããã ããã§ããèªåãåãã¦è§¦ãè¨èªã§åããç¬éã¯ã¨ã¦ãå¬ããããããä½åº¦ãä½åº¦ãèµ·ããããã§ããããæ¬å½ã«ãã®ãã£ã¬ã³ã¸ã¯æ¥½ããã£ãã§ãã
ã©ããªè¨èªã«ããå¾æä¸å¾æããããã¾ãã ã©ããªè¨èªã«ããè¯ãã¨ããã¨æªãã¨ãããããã¾ãã ç´ æ´ãããåã·ã¹ãã ã®ä»£åãã³ã³ãã¤ã«æéã ã£ãããå®è¡æããã©ã¼ãã³ã¹ã®ä»£åãã¡ã¢ãªã¼é åã«é¢ããèå¼±æ§ã ã£ãããã¾ãã æ´å²ã®ããè¨èªãããã°ãæ´å²ã®æµ ãè¨èªãããã¾ãã æ§ã ãªè¨èªãç 究ããä¸ã§ä½ãããè¨èªãããã°ãæ§ã ãªè¨èªã«å¤å¤§ãªå½±é¿ãåã¼ããè¨èªãããã¾ãã
大äºãªãã¨ã¯ãç®çã«æ²¿ã£ã¦é©åãªéå ·ãé¸ã¶ãã¨ã§ãã ä»äºã§æ°ããææ¦ãã§ããªãã£ãã¨ãã¦ããããã°ã©ãã¼ã¨ãã¦çãã¦ããä¸ã§ãè²ã ãªè¨èªã®ç¹æ§ãç¥ã£ã¦ãããã¨ã¯å¤§äºã ã¨æãã¾ãã å°ãªãã¨ãå¦çç³»ãèªåã®ã©ãããããã«å ¥ãã¦ã³ã¼ããå®è¡ããããããã¥ã¡ã³ããæ¢ãã¾ãã£ãã¨ããçµé¨ãããã®ã¨ãªãã®ã§ã¯ãè¨èªã«å¯¾ããå¿ççéå£ãã ãã¶éã£ã¦ãã¾ãã
ããåé¡ãæ§ã ãªè¨èªã§æ¸ãã¦ã¿ãã¨ãã課é¡ã¯ãæè¡ãæ·±ãã第ä¸æ©ã«éãã¾ããã 次ã®ã¹ãããã¯ãããããã£ããã«èå³ãæã£ãè¨èªãæ´ã«èª¿ã¹ã¦èº«ã«ä»ããã¨ãããã¨ã«ãªãã§ãããã ç§ã¯ããã¾ã§Haskell, Scala, Go, JavaScriptã¨ãã£ãè¨èªãæ¸ãã¦ãã¾ããããä»åã®ãã£ã¬ã³ã¸ã§æ°ãã«Rust, OCaml, Erlang, Clojureãªã©ã«ãèå³ãæã¤ããã«ãªãã¾ããã ããã¾ã§æ¸ãã¦ã¿ããã¨æããã¨ãããªãã£ãè¨èªã§ãã ããããæ´»èºããå ´é¢ãç°ãªã£ã¦ããããããã身ã«ã¤ãããã¨ã§ãããå¤ãã®å ´é¢ã§é©åãªè¨èªé¸æãã§ããããã«ãªããããããªãã¨æã£ã¦ãã¾ãã
ããªããè²ã ãªè¨èªã触ã£ã¦ã¿ã¾ãããï¼ä¹ä¹è¡¨ã§ãããããProject Eulerã§ãããããæ°å¼å¦çç³»ã§ãããããJSONãã¼ãµã¼ã§ããæ°ç¬ã½ã«ãã¼ã§ããHTTP echo serverã§ãããã¨æãã¾ãã大ããããªãåé¡ãé¸ã¶ãã¨ã¨ãä¸ã¤ã®è¨èªã«æéãããéããªããã¨ã30ç¨åº¦ã®è¨èª (ãããã¯ãã以ä¸) ã§æ¸ãã¦ã¿ããã¨ã大äºã§ããããã¦ãå ¬å¼ã®ããã¥ã¡ã³ããè¦ããã¨ããã¡ãã¨å¦çç³»ãã¤ã³ã¹ãã¼ã«ãã¦å®è¡ãããã¨ãã§ããã°ãã¹ããéããã¨ãå®è£ è¨èªãå¢ãã¦ãããå ¨ã¦ã®è¨èªã§ãã¹ããéããã¨ã¯ã¨ã¦ã楽ãããã¨ã§ãã
ãããåé¡ã¯è¨å®ã§ãã¾ãããï¼æ¬¡ã¯ããªãã®çªã§ããã
ç´ æµãªè¨èªã¨ã®åºä¼ããããããã¨
ããã¦ãããªãã®ããã°è¨äºããå¾ ã¡ãã¦ããã¾ãã
ãã¨ãã â æ¯è¼ããã°ã©ãã³ã°è¨èªå¦ã夢è¦ã¦
以åãmoznionããã¨ããæ¹ãYAPC Asia Hachioji 2016ã§ã®ãã¼ã¯ã®ææ³ã¨ã³ããªã¼ã¨ãã¦æ¬¡ã®è¨äºãæ¸ããã¦ãã¾ããã
ããããã ããæãã¾ããã ãã®ã¨ã³ããªã¼ãè¦ãæç¹ã§ãfastinvsqrtã15è¨èªãããã¾ã§é²ãã§ãã¦ããã®ããã°è¨äºã®ç¨æãé²ãã¦ããã¨ããã§ããã
ããããå·éã«ãªã£ã¦ã¿ãã°ãä¸ã¤ã®ã¢ã«ã´ãªãºã ããããããªè¨èªã§æ¸ãã¾ãããã¨ããã®ã¯å®æçã«èª°ããè¨ã£ã¦ãããã¨ã§ãããæ ã¦ã¦åºããããããã£ã¨è¨èªãå¢ããã¦ãããã£ããè¨èªæ¯è¼ãã¤ã¤åºãããã¨ããæ°æã¡ãé«ã¾ããå ¬éããã¾ã§ã«æéãå°ãããã£ã¦ãã¾ãã¾ããã 20è¨èªãè¶ ãããããããé²æãæªããªãããã£ã10è¡ç¨åº¦ã®ã³ã¼ããæ¸ãã®ã«æ°æ¥ããã£ãããã¦ãã¾ããã å®è£ ãããã¨æã£ã¦å¿ æ»ã«ãªã£ããã©çµå±æ¸ããªãã£ãè¨èªãããã¾ããã ã§ããããããããèªåã«ã¨ã£ã¦ããçµé¨ã«ãªã£ãã¨æãã¾ãã
èªç¶è¨èªã®ç 究åéã®ä¸ã¤ã«ãæ¯è¼è¨èªå¦ã¨ããåéãããã¾ãã æ°æã®ç§»åã«ããè¨èªã¯åè£ããã¾ãæåã®äº¤æµã«ããå½±é¿ããã£ã¦ãã¾ããã é¢é£ãã¦ããè¨èªã®ææ³ãé³é»ãæ¯è¼ç 究ãããã¨ã§è¨èªã®ã«ã¼ãã辿ãã®ãæ¯è¼è¨èªå¦ã®ä¸»ããç®çã§ãã ç§ã¯å¤§å¦æ代ã«ä¸è¬æé¤ã®ç§ç®ã§ãã®åéã®è¬ç¾©ãåãã¦ãè¬è§£ãã¿ããã§ã¨ã¦ããããããã¨æãã¾ããã
ããããè¨èªã§ä¸ã¤ã®ã¢ã«ã´ãªãºã ãæ¸ãã¦ã¿ãã¨ããã®ã¯ãã¹ãã«ã®åä¸ãè¨èªç解ãããããã£ã¨æ·±ãæ義ãããããã«æãã¾ãã ç§ã¯ãã®ã¨ã³ããªã¼ãç¨æããä¸ã§ããæ¯è¼ããã°ã©ãã³ã°è¨èªå¦ãã¨ãããã®ãå¦æ³ãã¾ããã è¨èªã¯ä»ã®è¨èªã®å½±é¿ãåãã¦çã¾ããä»ã®è¨èªã«å½±é¿ãä¸ããªããæé·ããããã¦å»ãã¦ããã¾ãã æ§æããã¼ã¯ã¼ããããæ¼ç®åãé¢æ°åãªã©ç´°é¨ãæ¯è¼ãã¦ããã¨ãè¨èªè¨è ãå½±é¿ãåããè¨èªããè¨èªã®è¨è¨ææ³ããããã«ãªã£ã¦ãã¾ãã
ãªããåãããªãã¨æ¸ãã¦ãã¾ããããä¼¼ããããªãã¨è¨ã£ã¦ãã人ã¯ä»ã«ããªãã®ããªã¨èª¿ã¹ã¦ã¿ããã以ä¸ã®è¨äºãè¦ã¤ãã¦ãã¾ãã¾ããã
æµç³ã§ãã西尾å çã å½æãã®è¨äºãè¦ããã©ããè¦ãã¦ãã¾ãããããããã風ã«è¨èªã観å¯ããäºã®é¢ç½ãã«ãç§ã¯ããããæ°ãä»ãã¾ãããï¼ ã©ããªã«äººã«è¨ããã¦ããããã¨ããªãã£ããã¨ã§ãããµã¨å§ãããé¢ç½ãã¦å¤¢ä¸ã«ãªã£ã¦ãã¾ãã¾ããã ã§ãã人ãæé·ããã£ã¦ãããããã¨ã§ãããï¼
ã¨ã³ã¸ãã¢åé
ã¯ã¦ãªã§ã¯ãèªãç é½ãæè¡ãæ·±ããããããå ´é¢ã§é©åãªéå ·ã使ãåããããããã«ãªãããããããªæ欲çãªã¨ã³ã¸ãã¢ãåéãã¦ãã¾ãã