Posted to tcl by sebres at Thu Aug 29 14:15:30 GMT 2019view raw

  1. /*
  2. * tclfastinvsqrt.c --
  3. *
  4. * Test module to get native handle of channel.
  5. *
  6. * Compile:
  7. * mingw: gcc -O2 -DUSE_TCL_STUBS=1 -I$tcl/win -I$tcl/generic tclfastinvsqrt.c -shared -o tclfastinvsqrt.dll libtclstub86.a
  8. * *nix: gcc -O2 -DUSE_TCL_STUBS=1 -I$tcl/unix -I$tcl/generic tclfastinvsqrt.c -shared -o tclfastinvsqrt.so libtclstub86.a
  9. *
  10. * Usage:
  11. * $ tclsh86
  12. * % load tclfastinvsqrt
  13. * % expr {invsqrt(10)}
  14. */
  15.  
  16. #include "tcl.h"
  17.  
  18. static inline double
  19. FastInvSqrt(double x, int accuracy) {
  20. char *buf = (char *)&x;
  21. double xhalf = 0.5f * x;
  22. Tcl_WideInt i = *(Tcl_WideInt*)buf;
  23. i = 0x5fe6eb50c7b537a9 - (i >> 1);
  24. buf = (char *)&i;
  25. x = *(double*)buf;
  26. while (accuracy--) {
  27. x = x*(1.5-(xhalf*x*x));
  28. }
  29. return x;
  30. }
  31.  
  32. int
  33. FastInvSqrtCmd(
  34. ClientData dummy,
  35. Tcl_Interp* interp,
  36. int objc,
  37. Tcl_Obj * const objv[]
  38. ) {
  39. double dbl;
  40. int accuracy = 4;
  41.  
  42. if (objc < 2 || objc > 3) {
  43. Tcl_WrongNumArgs(interp, 1, objv, "value ?accuracy?");
  44. return TCL_ERROR;
  45. }
  46.  
  47. if (Tcl_GetDoubleFromObj(interp, objv[1], &dbl) != TCL_OK) {
  48. return TCL_ERROR;
  49. }
  50. if (objc > 2 && Tcl_GetIntFromObj(interp, objv[2], &accuracy) != TCL_OK) {
  51. return TCL_ERROR;
  52. }
  53.  
  54. dbl = FastInvSqrt(dbl, accuracy);
  55.  
  56. Tcl_SetObjResult(interp, Tcl_NewDoubleObj(dbl));
  57. return TCL_OK;
  58. }
  59.  
  60. int
  61. Tclfastinvsqrt_Init(Tcl_Interp *interp) {
  62. if (!Tcl_InitStubs(interp, "8.5", 0)) {
  63. return TCL_ERROR;
  64. }
  65. Tcl_CreateObjCommand(interp, "::tcl::mathfunc::invsqrt", FastInvSqrtCmd, NULL, NULL);
  66. return TCL_OK;
  67. }
  68.  
  69. /*
  70.  
  71. load tclfastinvsqrt
  72.  
  73. # speed vs accuracy:
  74.  
  75. set tm 500
  76. for {set x 2} {$x < 100000} {set x [expr {$x * 10}]} {
  77. puts $x:\t[timerate { expr { 1 / sqrt($x) } } $tm]
  78. puts \t[timerate { expr { invsqrt($x,1) } } $tm]
  79. puts \t[timerate { expr { invsqrt($x) } } $tm]
  80. }
  81.  
  82. # accuracy :
  83.  
  84. for {set x 2} {$x < 100000} {set x [expr {$x * 10}]} {
  85. puts $x:\t[expr { 1 / sqrt($x) }]
  86. puts \t[expr { invsqrt($x) }]
  87. }
  88. for {set x 2} {$x < 100000} {set x [expr {$x * 10}]} {
  89. puts $x:\t[expr { 1 / sqrt($x) }]
  90. puts \t[expr { invsqrt($x,1) }]
  91. }
  92.  
  93. # Herbie example:
  94.  
  95. for {set x 2} {$x < 100000} {set x [expr {$x * 10}]} {
  96. puts $x:\t[expr { sqrt($x+1) - sqrt($x) }]
  97. puts \t[expr { 1 / (sqrt($x+1) + sqrt($x)) }]
  98. puts \t[expr { invsqrt( (2*$x + 1 + 2/invsqrt(($x+1)*$x)) ) }]
  99. }
  100.  
  101. */

Comments

Posted by sebres at Thu Aug 29 15:02:08 GMT 2019 [text] [code]

the comments about channel was copy&paste, simply ignore it :)