├── deterministic ├── deterministic_float_android │ ├── .idea │ │ ├── .name │ │ ├── vcs.xml │ │ ├── misc.xml │ │ ├── runConfigurations.xml │ │ ├── gradle.xml │ │ ├── jarRepositories.xml │ │ └── codeStyles │ │ │ └── Project.xml │ ├── app │ │ ├── .gitignore │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ ├── colors.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ ├── layout │ │ │ │ │ │ └── activity_main.xml │ │ │ │ │ ├── drawable-v24 │ │ │ │ │ │ └── ic_launcher_foreground.xml │ │ │ │ │ └── drawable │ │ │ │ │ │ └── ic_launcher_background.xml │ │ │ │ ├── cpp │ │ │ │ │ ├── native-lib.cpp │ │ │ │ │ └── CMakeLists.txt │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── testcpp │ │ │ │ │ └── MainActivity.java │ │ │ ├── test │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── testcpp │ │ │ │ │ └── ExampleUnitTest.java │ │ │ └── androidTest │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── testcpp │ │ │ │ └── ExampleInstrumentedTest.java │ │ ├── proguard-rules.pro │ │ └── build.gradle │ ├── settings.gradle │ ├── zhouxuan.jks │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── build.gradle │ ├── gradle.properties │ ├── gradlew.bat │ └── gradlew ├── deterministic_float.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcuserdata │ │ │ └── zhouxuan.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcuserdata │ │ └── zhouxuan.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── deterministic_float.xcscheme │ └── project.pbxproj ├── deterministic_float_ios.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── project.pbxproj ├── deterministic_float.h ├── main.cpp ├── main.mm ├── deterministic_float_win │ ├── deterministic_float.sln │ ├── deterministic_float.vcxproj.filters │ ├── deterministic_float.natvis │ └── deterministic_float.vcxproj ├── glacier_platform.h ├── glacier_float.h ├── deterministic_float.cpp └── glacier_float.cpp ├── README.md ├── Test_BenchMark_MacOS_M1Pro.md ├── Test_BenchMark_Android_P40_KIRIN_990.md ├── Test_BenchMark_Win_12900H.md ├── Test_BenchMark_iPhone13_ProMax_A15.md ├── Test_BenchMark_Win_5950X.md ├── Test_BenchMark_Android_S9_Snapdragon845.md └── LICENSE /deterministic/deterministic_float_android/.idea/.name: -------------------------------------------------------------------------------- 1 | testcpp -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | rootProject.name = "testcpp" -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | testcpp 3 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/zhouxuan.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/zhouxuan.jks -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /deterministic/deterministic_float.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float_android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /deterministic/deterministic_float_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /deterministic/deterministic_float.xcodeproj/project.xcworkspace/xcuserdata/zhouxuan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devlinzhou/deterministic_float/HEAD/deterministic/deterministic_float.xcodeproj/project.xcworkspace/xcuserdata/zhouxuan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Oct 17 19:06:43 CST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip 7 | -------------------------------------------------------------------------------- /deterministic/deterministic_float.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/test/java/com/example/testcpp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.example.testcpp; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/cpp/native-lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../../../../../deterministic_float.h" 5 | #include 6 | 7 | #define LOG_TAG "foo" 8 | 9 | extern "C" JNIEXPORT jstring JNICALL 10 | Java_com_example_testcpp_MainActivity_stringFromJNI( 11 | JNIEnv* env, 12 | jobject /* this */) 13 | { 14 | std::string hello = "Helloasdfasfs from C++"; 15 | 16 | TestGFloat TG; 17 | TG.Run(); 18 | 19 | return env->NewStringUTF(hello.c_str()); 20 | } 21 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath "com.android.tools.build:gradle:4.0.0" 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | task clean(type: Delete) { 23 | delete rootProject.buildDir 24 | } -------------------------------------------------------------------------------- /deterministic/deterministic_float.xcodeproj/xcuserdata/zhouxuan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | deterministic_float.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | FA38AAE828D07A9200ED6160 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /deterministic/deterministic_float.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 zhou xuan, Email: zhouxuan6676@gmail.com 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at * 6 | * http://www.apache.org/licenses/LICENSE-2.0 * 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | #pragma once 14 | 15 | 16 | 17 | 18 | #include 19 | 20 | class TestGFloat 21 | { 22 | public: 23 | 24 | void Run(); 25 | }; 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /deterministic/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 zhou xuan, Email: zhouxuan6676@gmail.com 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at * 6 | * http://www.apache.org/licenses/LICENSE-2.0 * 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | #include "deterministic_float.h" 15 | 16 | int main(int argc, char * argv[]) 17 | { 18 | TestGFloat TG; 19 | TG.Run(); 20 | 21 | return 0; 22 | } 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /deterministic/main.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 zhou xuan, Email: zhouxuan6676@gmail.com 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at * 6 | * http://www.apache.org/licenses/LICENSE-2.0 * 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | 15 | #import "deterministic_float.h" 16 | 17 | 18 | 19 | int main(int argc, char * argv[]) 20 | { 21 | TestGFloat TG; 22 | TG.Run(); 23 | 24 | return 0; 25 | } 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/androidTest/java/com/example/testcpp/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.testcpp; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.example.testcpp", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/java/com/example/testcpp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.testcpp; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import android.os.Bundle; 6 | import android.widget.TextView; 7 | 8 | public class MainActivity extends AppCompatActivity { 9 | 10 | // Used to load the 'native-lib' library on application startup. 11 | static { 12 | System.loadLibrary("native-lib"); 13 | } 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_main); 19 | 20 | // Example of a call to a native method 21 | TextView tv = findViewById(R.id.sample_text); 22 | tv.setText(stringFromJNI()); 23 | } 24 | 25 | /** 26 | * A native method that is implemented by the 'native-lib' native library, 27 | * which is packaged with this application. 28 | */ 29 | public native String stringFromJNI(); 30 | } 31 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_win/deterministic_float.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.32319.34 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deterministic_float", "deterministic_float.vcxproj", "{C940A429-F527-4415-8B80-143DAB3DCD69}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {C940A429-F527-4415-8B80-143DAB3DCD69}.Debug|x64.ActiveCfg = Debug|x64 17 | {C940A429-F527-4415-8B80-143DAB3DCD69}.Debug|x64.Build.0 = Debug|x64 18 | {C940A429-F527-4415-8B80-143DAB3DCD69}.Debug|x86.ActiveCfg = Debug|Win32 19 | {C940A429-F527-4415-8B80-143DAB3DCD69}.Debug|x86.Build.0 = Debug|Win32 20 | {C940A429-F527-4415-8B80-143DAB3DCD69}.Release|x64.ActiveCfg = Release|x64 21 | {C940A429-F527-4415-8B80-143DAB3DCD69}.Release|x64.Build.0 = Release|x64 22 | {C940A429-F527-4415-8B80-143DAB3DCD69}.Release|x86.ActiveCfg = Release|Win32 23 | {C940A429-F527-4415-8B80-143DAB3DCD69}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {12D26FB7-52B0-499C-8601-67F7CC833BCF} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_win/deterministic_float.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 源文件 29 | 30 | 31 | 32 | 33 | 头文件 34 | 35 | 36 | 头文件 37 | 38 | 39 | 头文件 40 | 41 | 42 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | signingConfigs { 5 | release { 6 | storeFile file('C:\\Users\\zhouxuan\\AndroidStudioProjects\\testcpp\\zhouxuan.jks') 7 | storePassword 'zhouxuan' 8 | keyAlias 'key0' 9 | keyPassword 'zhouxuan' 10 | } 11 | debug { 12 | storeFile file('C:\\Users\\zhouxuan\\AndroidStudioProjects\\testcpp\\zhouxuan.jks') 13 | storePassword 'zhouxuan' 14 | keyAlias 'key0' 15 | keyPassword 'zhouxuan' 16 | } 17 | } 18 | compileSdkVersion 33 19 | buildToolsVersion "30.0.0" 20 | 21 | defaultConfig { 22 | applicationId "com.example.testcpp" 23 | minSdkVersion 16 24 | targetSdkVersion 33 25 | versionCode 1 26 | versionName "1.0" 27 | 28 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 29 | externalNativeBuild { 30 | cmake { 31 | cppFlags "-std=c++14" 32 | } 33 | } 34 | } 35 | 36 | buildTypes { 37 | release { 38 | minifyEnabled false 39 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 40 | signingConfig signingConfigs.release 41 | } 42 | } 43 | externalNativeBuild { 44 | cmake { 45 | path "src/main/cpp/CMakeLists.txt" 46 | version "3.10.2" 47 | } 48 | } 49 | } 50 | 51 | dependencies { 52 | implementation fileTree(dir: "libs", include: ["*.jar"]) 53 | implementation 'androidx.appcompat:appcompat:1.1.0' 54 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 55 | testImplementation 'junit:junit:4.12' 56 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 57 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 58 | 59 | } 60 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_win/deterministic_float.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{Frac={((rawint32 >> 8)/4194304.f ) * ( 1 << uint64_t( (rawint32 & 255 )-127+22))}, 2^= {int32_t((rawint32 & 255 )-127)}}} 7 | {{Frac={((rawint32 >> 8)/4194304.f ) / ( 1 << uint64_t(-((rawint32 & 255 )-127+22)))}, 2^= {int32_t((rawint32 & 255 )-127)}}} 8 | rawint32 9 | 10 | 11 | 12 | 13 | {{ Frac={rawInt32 /256.f } }} 14 | rawInt32 15 | 16 | 17 | 18 | {{ Frac={rawInt32 /65536.f } }} 19 | rawInt32 20 | 21 | 22 | 23 | {{ Frac={rawInt32 /134217728.f } }} 24 | rawInt32 25 | 26 | 27 | {{ Frac={rawInt32 /268435456.f } }} 28 | rawInt32 29 | 30 | 31 | 32 | {{ Frac={rawInt32 /536870912.f } }} 33 | rawInt32 34 | 35 | 36 | {{ Frac={rawInt32 /1073741824.f } }} 37 | rawInt32 38 | 39 | 40 | 41 | {{ Frac={rawInt64 /4294967296.f } }} 42 | rawInt32 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.4.1) 7 | 8 | # Creates and names a library, sets it as either STATIC 9 | # or SHARED, and provides the relative paths to its source code. 10 | # You can define multiple libraries, and CMake builds them for you. 11 | # Gradle automatically packages shared libraries with your APK. 12 | 13 | add_library( # Sets the name of the library. 14 | native-lib 15 | 16 | # Sets the library as a shared library. 17 | SHARED 18 | 19 | # Provides a relative path to your source file(s). 20 | native-lib.cpp 21 | ../../../../../glacier_float.cpp 22 | ../../../../../deterministic_float.cpp 23 | ) 24 | 25 | # Searches for a specified prebuilt library and stores the path as a 26 | # variable. Because CMake includes system libraries in the search path by 27 | # default, you only need to specify the name of the public NDK library 28 | # you want to add. CMake verifies that the library exists before 29 | # completing its build. 30 | 31 | find_library( # Sets the name of the path variable. 32 | log-lib 33 | 34 | # Specifies the name of the NDK library that 35 | # you want CMake to locate. 36 | log ) 37 | 38 | # Specifies libraries CMake should link to your target library. You 39 | # can link multiple libraries, such as libraries you define in this 40 | # build script, prebuilt third-party libraries, or system libraries. 41 | 42 | target_link_libraries( # Specifies the target library. 43 | native-lib 44 | 45 | # Links the target library to the log library 46 | # included in the NDK. 47 | ${log-lib} ) -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /deterministic/deterministic_float.xcodeproj/xcshareddata/xcschemes/deterministic_float.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## deterministic_float 2 | * Cross-platform deterministic float point, fast soft float point. 3 | * Fast soft float point for deterministic computing, That 4 | you can make **deterministic plugin** by use GFloat to replace float-point. like: 5 | * Physics Engine (Bullet、PhysX) 6 | * AI Path Finding (Recast Navigation) 7 | * AI Engine 8 | * Compare the overall performance of hard float IEEE-754 and GFloat numbers, They differ by no more than 500%, Refer to the multiply-add instructions for measuring the computing power of the graphics card. compare multiply and add function: 9 | 10 | 11 | 12 | * 跨平台的确定性浮点数,高性能的软件浮点数 13 | * 你可以使用GFloat替代各种中间件的浮点数,从而实现带确定性的计算,实现帧同步游戏逻辑,也可以实现加密货币计算逻辑,例如: 14 | * 物理引擎(Bullet、PhysX) 15 | * AI 寻路(Recast Navigation) 16 | * AI 引擎 17 | * 整体上GFloat与IEEE754的硬件浮点数float,性能差距在500%以内。参考显卡衡量计算能力的乘加指令,主要比较乘法和加法函数的性能: 18 | 19 | ### IEEE-754 float & GFloat 20 | * IEEE-754 float 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
signexponents(8 bits)fractions(23 bits)
313029...24232221...10
33 | 34 | * $\mathbf{X}_{IEEE754} = (-1)^\mathbf{sign} \times (1.\mathbf{fraction}) \times 2 ^{\mathbf{exponent} - 127}$ 35 | * GFloat 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
signfractions(23 bits)exponents(8 bits)
313029...9876...10
48 | 49 | * $\mathbf{X}_{GFloat} = (-1)^\mathbf{sign} \times (\mathbf{fraction}) \times 2 ^{\mathbf{exponent} - 127}$ 50 | 51 | 52 | 53 | ## Performance float(IEEE-754) vs GFloat 54 | * Several important functions compare, for more information to view TestAndBenchMark 55 | * Call every function 1000000 Times, get the float vs GFloat time 56 | 57 | Platform|Win64 |Win64 | iOS | OSX | Android | 58 | |:--|:--:|:--:|:--:|:--:|:--:| 59 | |CPU|Ryzen-5950X|i9-12900H| Apple A15|Apple M1Pro|HiSilicon-KIRIN-990| 60 | | |float vs GFloat| float vs GFloat| float vs GFloat|float vs GFloat |float vs GFloat 61 | |Add|0.63 vs 2.63 ms| 0.44 vs 1.48ms| 0.43 vs 1.85 ms|0.34 vs 2.24 ms | 0.89 vs 8.76 ms 62 | |Mul|0.70 vs 1.14 ms| 0.52 vs 0.79 ms| 0.42 vs 0.78 ms |0.34 vs 0.93 ms|0.62 vs 2.10 ms 63 | |Sin|10.20 vs 8.39 ms|8.6 vs 3.15 ms| 3.6 vs 4.9 ms|2.29 vs 5.28 ms | 11.58 vs 15.75 ms 64 | |Sqrt|1.08 vs 9.29 ms|0.7 vs 6.2 ms|0.83 vs 5.64 ms |0.64 vs 6.06 ms| 0.65 vs 15.77 ms 65 | |Exp| 2.06 vs 10.83ms| 2.15 vs 24.52ms|5.52 vs 7.03 ms|5.75 vs 6.52 ms| 6.06 vs 20.90 ms 66 | 67 | ## How to start 68 | * Four OS platform projects for fast and easy to start test&benchmark 69 | 70 | |Target Platform| Compiler| Project | 71 | |:--|:--|:--| 72 | |Win|Visual Studio 2022| deterministic/deterministic_float.sln| 73 | |MacOS|XCode 13.4| deterministic/deterministic_float.xcodeproj | 74 | |iOS|XCode 13.4| deterministic/deterministic_float_ios.xcodeproj | 75 | |Android|Android studio 4.0|deterministic/deterministic_float_android| 76 | 77 | ## Current Support Platform For Test&Benchmark 78 | |Operation System|Win64|MacOS| iOS| Android| 79 | |--|:--:|:--:|:--:|:--:| 80 | | | $\checkmark$ |$\checkmark$|$\checkmark$| $\checkmark$ | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /Test_BenchMark_MacOS_M1Pro.md: -------------------------------------------------------------------------------- 1 | # GFloat Test And BenchMark 2 | * Test time : Tue Oct 11 14:49:21 2022 3 | 4 | |Operation System| C++ Compiler version |CPU | Base Frequency | 5 | |:--:|:--:|:--:|:--:| 6 | |Mac OSX|Apple LLVM 13.1.6 (clang-1316.0.21.2.5)|Apple Arm CPU|0.024 GHz or 0.024 GHz | 7 | * Performance: float vs GFloat, Call 1000000 times 8 | * Error : the relative error between cmath (double) and GFloat Math 9 | 10 | |Function| avg error|max error| max abs error|float vs GFloat | float / GFloat | 11 | |:--|--:|--:|--:|--:|--| 12 | |Add | 0.000004 %| 0.000024 %| 0.003906| 0.34 vs 5.78 (ms)|0.06 | 13 | |Sub | 0.000004 %| 0.000024 %| 0.003906| 0.34 vs 5.95 (ms)|0.06 | 14 | |Mul | 0.000012 %| 0.000048 %| 32.000000| 0.34 vs 0.92 (ms)|0.37 | 15 | |Div | 0.000009 %| 0.000024 %| 0.031250| 0.38 vs 1.69 (ms)|0.23 | 16 | |Ceil | 0.000000 %| 0.000000 %| 0.000000| 0.18 vs 1.63 (ms)|0.11 | 17 | |Floor | 0.000000 %| 0.000000 %| 0.000000| 0.18 vs 0.77 (ms)|0.24 | 18 | |Whole | 0.000000 %| 0.000000 %| 0.000000| 0.20 vs 1.42 (ms)|0.14 | 19 | |WholeFrac | 0.000000 %| 0.000000 %| 0.000000| 0.17 vs 5.71 (ms)|0.03 | 20 | |Fraction | 0.000000 %| 0.000000 %| 0.000000| 0.18 vs 3.30 (ms)|0.06 | 21 | |-() | 0.000000 %| 0.000000 %| 0.000000| 0.20 vs 0.52 (ms)|0.38 | 22 | |>() | 0.000000 %| 0.000000 %| 0.000000| 0.38 vs 7.76 (ms)|0.05 | 23 | |<() | 0.000000 %| 0.000000 %| 0.000000| 0.32 vs 7.98 (ms)|0.04 | 24 | |>=() | 0.000000 %| 0.000000 %| 0.000000| 0.33 vs 7.82 (ms)|0.04 | 25 | |<=() | 0.000000 %| 0.000000 %| 0.000000| 0.34 vs 1.73 (ms)|0.20 | 26 | |Abs | 0.000000 %| 0.000000 %| 0.000000| 0.18 vs 0.53 (ms)|0.34 | 27 | |Normalize32 | 0.000000 %| 0.000000 %| 0.000000| 0.17 vs 1.05 (ms)|0.16 | 28 | |Normalize64 | 0.000000 %| 0.000000 %| 0.000000| 0.17 vs 1.07 (ms)|0.16 | 29 | |FromInt | 0.000000 %| 0.000000 %| 0.000000| 0.19 vs 0.97 (ms)|0.20 | 30 | |Fromfloat | 0.000000 %| 0.000000 %| 0.000000| 0.17 vs 0.17 (ms)|1.00 | 31 | |CeilToInt | 0.000000 %| 0.000000 %| 0.000000| 0.18 vs 2.34 (ms)|0.08 | 32 | |FloorToInt | 0.000000 %| 0.000000 %| 0.000000| 0.18 vs 1.97 (ms)|0.09 | 33 | |Sin | 0.000099 %| 4.559921 %| 0.000005| 3.72 vs 5.17 (ms)|0.72 | 34 | |Cos | 0.001806 %| 0.122642 %| 0.000028| 3.78 vs 5.50 (ms)|0.69 | 35 | |Tan | 0.001776 %| 4.562861 %| 83.726562| 8.10 vs 13.61 (ms)|0.59 | 36 | |ASin | 0.031373 %| 100.000000 %| 0.049958| 2.78 vs 7.63 (ms)|0.36 | 37 | |ACos | 0.117627 %| 98.413861 %| 0.049958| 3.41 vs 10.90 (ms)|0.31 | 38 | |ATan | 0.003567 %| 0.036536 %| 0.000166| 2.58 vs 10.99 (ms)|0.23 | 39 | |ATan(10,x) | 0.006190 %| 0.021383 %| 0.000166| 4.79 vs 15.22 (ms)|0.31 | 40 | |ATan(x,10) | 0.007318 %| 0.230349 %| 0.000166| 4.54 vs 13.93 (ms)|0.33 | 41 | |Sqrt | 0.000038 %| 0.000084 %| 0.000076| 0.67 vs 5.44 (ms)|0.12 | 42 | |InvSqrt | 0.000026 %| 0.000062 %| 0.000183| 0.95 vs 4.35 (ms)|0.22 | 43 | |Exp | 0.001698 %| 0.050661 %| 19760.000000| 5.57 vs 6.61 (ms)|0.84 | 44 | |Pow2 | 0.001820 %| 0.050354 %| 72448.000000| 2.00 vs 5.41 (ms)|0.37 | 45 | |Log_e | 0.001206 %| 86.225453 %| 0.000031| 1.91 vs 3.55 (ms)|0.54 | 46 | |Log_2 | 0.001206 %| 86.225884 %| 0.000043| 1.96 vs 3.13 (ms)|0.63 | 47 | |Log_10 | 0.001206 %| 86.224927 %| 0.000013| 1.97 vs 3.54 (ms)|0.56 | 48 | |Pow(1.7,x) | 0.003043 %| 0.049457 %| 2121.500000| 4.39 vs 13.81 (ms)|0.32 | 49 | |Pow(x,1.7) | 0.006763 %| 0.055199 %| 0.015121| 4.50 vs 14.98 (ms)|0.30 | 50 | |Fmod(x,1.7) | 0.129491 %| 7214.285714 %| 1.700575|15.22 vs 12.09 (ms)|**1.26** | 51 | |Fmod(1.7,x) | 0.000327 %| 15.789474 %| 0.000000| 4.46 vs 6.04 (ms)|0.74 | 52 | -------------------------------------------------------------------------------- /Test_BenchMark_Android_P40_KIRIN_990.md: -------------------------------------------------------------------------------- 1 | # GFloat Test And BenchMark 2 | * Test time : Tue Oct 18 12:56:37 2022 3 | 4 | |Operation System| C++ Compiler version |CPU | Base Frequency | 5 | |:--:|:--:|:--:|:--:| 6 | |Linux|4.2.1 Compatible Android (5900059 based on r365631c) Clang 9.0.8 |Unkown CPU|0.00192 GHz or 0.001 GHz | 7 | 8 | * Performance: float vs GFloat, Call 1000000 times 9 | * Error : the relative error between cmath (double) and GFloat Math 10 | 11 | | Function | input data |avg error | max error | max abs error | float vs GFloat | float / GFloat | 12 | |:--|--:|--:|--:|--:|--:|--| 13 | |Add |[ -10000.0, 10000.0]| 0.000004 %| 0.000024 %| 0.003906| 0.89 vs 8.76 (ms)|0.10 | 14 | |Sub |[ -10000.0, 10000.0]| 0.000004 %| 0.000024 %| 0.003906| 0.64 vs 9.34 (ms)|0.07 | 15 | |Mul |[ -10000.0, 10000.0]| 0.000012 %| 0.000048 %| 32.000000| 0.62 vs 2.10 (ms)|0.29 | 16 | |Div |[ -10000.0, 10000.0]| 0.000009 %| 0.000024 %| 0.031250| 0.72 vs 4.75 (ms)|0.15 | 17 | |Ceil |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.37 vs 4.89 (ms)|0.08 | 18 | |Floor |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.37 vs 1.89 (ms)|0.20 | 19 | |Whole |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.45 vs 5.09 (ms)|0.09 | 20 | |WholeFrac |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.40 vs 12.01 (ms)|0.03 | 21 | |Fraction |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.48 vs 4.99 (ms)|0.10 | 22 | |-() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.36 vs 1.20 (ms)|0.30 | 23 | |>() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.59 vs 8.65 (ms)|0.07 | 24 | |<() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.55 vs 8.92 (ms)|0.06 | 25 | |>=() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.55 vs 9.00 (ms)|0.06 | 26 | |<=() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.54 vs 5.08 (ms)|0.11 | 27 | |Abs |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.37 vs 5.85 (ms)|0.06 | 28 | |Normalize32 |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.34 vs 2.64 (ms)|0.13 | 29 | |Normalize64 |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.36 vs 2.75 (ms)|0.13 | 30 | |FromInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.43 vs 2.03 (ms)|0.21 | 31 | |Fromfloat |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.36 vs 0.32 (ms)|**1.14** | 32 | |CeilToInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.37 vs 4.11 (ms)|0.09 | 33 | |FloorToInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.38 vs 3.69 (ms)|0.10 | 34 | |Sin |[ -10000.0, 10000.0]| 0.000099 %| 4.559921 %| 0.000005|11.58 vs 15.75 (ms)|0.74 | 35 | |Cos |[ -10000.0, 10000.0]| 0.001805 %| 0.122642 %| 0.000028|11.71 vs 15.31 (ms)|0.76 | 36 | |Tan |[ -10000.0, 10000.0]| 0.001776 %| 4.562861 %| 83.726562|12.40 vs 36.10 (ms)|0.34 | 37 | |ASin |[ -1.0, 1.0]| 0.031373 %| 100.000000 %| 0.049958| 6.48 vs 27.32 (ms)|0.24 | 38 | |ACos |[ -1.0, 1.0]| 0.117627 %| 98.413861 %| 0.049958| 7.08 vs 39.70 (ms)|0.18 | 39 | |ATan |[ -10000.0, 10000.0]| 0.003567 %| 0.036536 %| 0.000166| 9.59 vs 29.17 (ms)|0.33 | 40 | |ATan(10,x) |[ -10000.0, 10000.0]| 0.006189 %| 0.021383 %| 0.000166|18.24 vs 36.38 (ms)|0.50 | 41 | |ATan(x,10) |[ -10000.0, 10000.0]| 0.007318 %| 0.230349 %| 0.000166|17.76 vs 34.05 (ms)|0.52 | 42 | |Sqrt |[ 0.0, 10000.0]| 0.000038 %| 0.000084 %| 0.000076| 0.65 vs 15.77 (ms)|0.04 | 43 | |InvSqrt |[ 0.0, 10000.0]| 0.000026 %| 0.000062 %| 0.000183| 1.14 vs 13.62 (ms)|0.08 | 44 | |Exp |[ -20.0, 20.0]| 0.001698 %| 0.050661 %| 19760.000000| 6.06 vs 20.90 (ms)|0.29 | 45 | |Pow2 |[ -30.0, 30.0]| 0.001820 %| 0.050354 %| 72448.000000| 5.62 vs 18.60 (ms)|0.30 | 46 | |Log_e |[ 0.0, 10000.0]| 0.001206 %| 86.225453 %| 0.000031| 6.30 vs 12.87 (ms)|0.49 | 47 | |Log_2 |[ 0.0, 10000.0]| 0.001206 %| 86.225898 %| 0.000043| 6.26 vs 11.89 (ms)|0.53 | 48 | |Log_10 |[ 0.0, 10000.0]| 0.001206 %| 86.224927 %| 0.000013|14.16 vs 12.88 (ms)|**1.10** | 49 | |Pow(1.7,x) |[ -30.0, 30.0]| 0.003043 %| 0.049457 %| 2121.500000|11.09 vs 36.09 (ms)|0.31 | 50 | |Pow(x,1.7) |[ 0.6, 20.0]| 0.006763 %| 0.055199 %| 0.015121|11.08 vs 40.55 (ms)|0.27 | 51 | |Fmod(x,1.7) |[ -10000.0, 10000.0]| 0.129491 %| 7214.285714 %| 1.700575|30.50 vs 24.91 (ms)|**1.22** | 52 | |Fmod(1.7,x) |[ -10000.0, 10000.0]| 0.000327 %| 15.789474 %| 0.000000| 9.93 vs 15.34 (ms)|0.65 | -------------------------------------------------------------------------------- /Test_BenchMark_Win_12900H.md: -------------------------------------------------------------------------------- 1 | # GFloat Test And BenchMark 2 | * Test time : Sun Oct 23 14:01:00 2022 3 | 4 | |Operation System| C++ Compiler version |CPU | Base Frequency | 5 | |:--:|:--:|:--:|:--:| 6 | |Windows 64-bit|Visual Studio :1931|12th Gen Intel(R) Core(TM) i9-12900H|2.92 GHz or 2.9 GHz | 7 | * Performance: float vs GFloat, Call 1000000 times 8 | * Error : the relative error between cmath (double) and GFloat Math 9 | 10 | | Function | input data range |avg relative error | max relative error | max abs error | float vs GFloat | float / GFloat | 11 | |:--|:--:|:--:|:--:|:--:|:--:|:--:| 12 | |Add |[ -10000.0, 10000.0]| 0.000004 %| 0.000024 %| 0.003906| 0.50 vs 5.95 (ms)|0.08 | 13 | |Sub |[ -10000.0, 10000.0]| 0.000004 %| 0.000024 %| 0.003906| 0.47 vs 6.03 (ms)|0.08 | 14 | |Mul |[ -10000.0, 10000.0]| 0.000009 %| 0.000024 %| 16.000000| 0.45 vs 1.19 (ms)|0.37 | 15 | |Div |[ -10000.0, 10000.0]| 0.000009 %| 0.000024 %| 0.031250| 0.73 vs 2.32 (ms)|0.31 | 16 | |Ceil |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 6.37 vs 2.46 (ms)|**2.59** | 17 | |Floor |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 6.44 vs 2.07 (ms)|**3.11** | 18 | |Whole |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.42 vs 4.13 (ms)|0.10 | 19 | |WholeFrac |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.35 vs 6.71 (ms)|0.05 | 20 | |Fraction |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.34 vs 4.35 (ms)|0.08 | 21 | |-() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.34 vs 0.94 (ms)|0.36 | 22 | |>() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.42 vs 3.79 (ms)|0.11 | 23 | |<() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.43 vs 7.61 (ms)|0.06 | 24 | |>=() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.46 vs 7.43 (ms)|0.06 | 25 | |<=() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.61 vs 4.33 (ms)|0.14 | 26 | |Abs |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.35 vs 4.88 (ms)|0.07 | 27 | |Normalize32 |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.35 vs 0.93 (ms)|0.37 | 28 | |Normalize64 |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.34 vs 0.89 (ms)|0.38 | 29 | |FromInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.42 vs 1.11 (ms)|0.38 | 30 | |Fromfloat |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.33 vs 0.47 (ms)|0.70 | 31 | |CeilToInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 5.66 vs 2.45 (ms)|**2.31** | 32 | |FloorToInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 6.65 vs 2.32 (ms)|**2.86** | 33 | |Sin |[ -10000.0, 10000.0]| 0.000099 %| 4.559921 %| 0.000005| 7.69 vs 6.73 (ms)|**1.14** | 34 | |Cos |[ -10000.0, 10000.0]| 0.001805 %| 0.122642 %| 0.000028| 8.21 vs 9.00 (ms)|0.91 | 35 | |Tan |[ -10000.0, 10000.0]| 0.001776 %| 4.562861 %| 83.726562| 8.09 vs 15.87 (ms)|0.51 | 36 | |ASin |[ -1.0, 1.0]| 0.031373 %| 100.000000 %| 0.049958| 6.94 vs 9.66 (ms)|0.72 | 37 | |ACos |[ -1.0, 1.0]| 0.117627 %| 98.413861 %| 0.049958| 6.99 vs 13.53 (ms)|0.52 | 38 | |ATan |[ -10000.0, 10000.0]| 0.003567 %| 0.036536 %| 0.000166| 8.57 vs 15.85 (ms)|0.54 | 39 | |ATan(10,x) |[ -10000.0, 10000.0]| 0.006190 %| 0.021383 %| 0.000166|10.84 vs 19.26 (ms)|0.56 | 40 | |ATan(x,10) |[ -10000.0, 10000.0]| 0.007318 %| 0.230349 %| 0.000166|10.72 vs 19.72 (ms)|0.54 | 41 | |Sqrt |[ 0.0, 10000.0]| 0.000034 %| 0.000072 %| 0.000061| 0.63 vs 9.78 (ms)|0.06 | 42 | |InvSqrt |[ 0.0, 10000.0]| 0.000026 %| 0.000062 %| 0.000183| 1.21 vs 7.58 (ms)|0.16 | 43 | |Exp |[ -20.0, 20.0]| 0.001689 %| 0.050400 %| 19056.000000| 2.00 vs 8.75 (ms)|0.23 | 44 | |Pow2 |[ -30.0, 30.0]| 0.001820 %| 0.050354 %| 72448.000000| 4.96 vs 5.99 (ms)|0.83 | 45 | |Log_e |[ 0.0, 10000.0]| 0.001206 %| 86.225453 %| 0.000031| 2.67 vs 3.78 (ms)|0.71 | 46 | |Log_2 |[ 0.0, 10000.0]| 0.001206 %| 86.225884 %| 0.000043|19.78 vs 3.61 (ms)|**5.49** | 47 | |Log_10 |[ 0.0, 10000.0]| 0.001206 %| 86.224927 %| 0.000013| 2.93 vs 3.92 (ms)|0.75 | 48 | |Pow(1.7,x) |[ -30.0, 30.0]| 0.003042 %| 0.049457 %| 2121.500000| 5.44 vs 18.85 (ms)|0.29 | 49 | |Pow(x,1.7) |[ 0.6, 20.0]| 0.006756 %| 0.055199 %| 0.015030| 5.60 vs 19.13 (ms)|0.29 | 50 | |Fmod(x,1.7) |[ -10000.0, 10000.0]| 0.230497 %| 99374.274554 %| 1.699998| 8.71 vs 11.31 (ms)|0.77 | 51 | |Fmod(1.7,x) |[ -10000.0, 10000.0]| 0.000582 %| 46.261917 %| 0.000001| 3.59 vs 7.70 (ms)|0.47 | 52 | -------------------------------------------------------------------------------- /Test_BenchMark_iPhone13_ProMax_A15.md: -------------------------------------------------------------------------------- 1 | # GFloat Test And BenchMark 2 |  * Test time : Fri Oct 21 11:21:32 2022 3 | 4 | |Operation System| C++ Compiler version |CPU  | Base Frequency  | 5 | |:--:|:--:|:--:|:--:| 6 | |Darwin|Apple LLVM 13.1.6 (clang-1316.0.21.2.5)|Apple iPhone14,3 Arch : ARM64_E|0.024 GHz or  0.024 GHz | 7 |  * Performance: float vs GFloat,  Call 1000000 times 8 |  * Error : the relative error between cmath (double) and GFloat Math  9 | 10 | | Function | input data range |avg relative error | max relative error | max abs error | float vs GFloat | float / GFloat | 11 | |:--|:--:|:--:|:--:|:--:|:--:|:--:| 12 | |Add         |[ -10000.0,  10000.0]|  0.000004 %|      0.000024 %|      0.003906| 0.46 vs  4.76  (ms)|0.10 | 13 | |Sub         |[ -10000.0,  10000.0]|  0.000004 %|      0.000024 %|      0.003906| 0.51 vs  4.88  (ms)|0.11 | 14 | |Mul         |[ -10000.0,  10000.0]|  0.000012 %|      0.000048 %|     32.000000| 0.48 vs  0.78  (ms)|0.62 | 15 | |Div         |[ -10000.0,  10000.0]|  0.000009 %|      0.000024 %|      0.031250| 0.52 vs  1.41  (ms)|0.37 | 16 | |Ceil        |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.27 vs  1.50  (ms)|0.18 | 17 | |Floor       |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.27 vs  0.72  (ms)|0.37 | 18 | |Whole       |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.31 vs  1.45  (ms)|0.22 | 19 | |WholeFrac   |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.27 vs  5.50  (ms)|0.05 | 20 | |Fraction    |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.29 vs  3.33  (ms)|0.09 | 21 | |-()         |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.29 vs  0.51  (ms)|0.57 | 22 | |>()         |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.46 vs 11.06  (ms)|0.04 | 23 | |<()         |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.67 vs  8.19  (ms)|0.08 | 24 | |>=()        |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.45 vs  7.97  (ms)|0.06 | 25 | |<=()        |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.57 vs  1.62  (ms)|0.35 | 26 | |Abs         |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.31 vs  0.54  (ms)|0.57 | 27 | |Normalize32 |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.29 vs  1.03  (ms)|0.28 | 28 | |Normalize64 |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.29 vs  1.02  (ms)|0.28 | 29 | |FromInt     |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.29 vs  0.87  (ms)|0.33 | 30 | |Fromfloat   |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.28 vs  0.36  (ms)|0.77 | 31 | |CeilToInt   |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.26 vs  2.30  (ms)|0.11 | 32 | |FloorToInt  |[ -10000.0,  10000.0]|  0.000000 %|      0.000000 %|      0.000000| 0.29 vs  1.95  (ms)|0.15 | 33 | |Sin         |[ -10000.0,  10000.0]|  0.000099 %|      4.559921 %|      0.000005| 3.67 vs  4.78  (ms)|0.77 | 34 | |Cos         |[ -10000.0,  10000.0]|  0.001806 %|      0.122642 %|      0.000028| 3.77 vs  5.19  (ms)|0.73 | 35 | |Tan         |[ -10000.0,  10000.0]|  0.001776 %|      4.562861 %|     83.726562| 6.30 vs 12.64  (ms)|0.50 | 36 | |ASin        |[     -1.0,      1.0]|  0.031373 %|    100.000000 %|      0.049958| 2.67 vs  7.09  (ms)|0.38 | 37 | |ACos        |[     -1.0,      1.0]|  0.117627 %|     98.413861 %|      0.049958| 3.28 vs 10.21  (ms)|0.32 | 38 | |ATan        |[ -10000.0,  10000.0]|  0.003567 %|      0.036536 %|      0.000166| 2.52 vs 10.47  (ms)|0.24 | 39 | |ATan(10,x)  |[ -10000.0,  10000.0]|  0.006190 %|      0.021383 %|      0.000166| 4.63 vs 14.24  (ms)|0.33 | 40 | |ATan(x,10)  |[ -10000.0,  10000.0]|  0.007318 %|      0.230349 %|      0.000166| 4.33 vs 13.40  (ms)|0.32 | 41 | |Sqrt        |[      0.0,  10000.0]|  0.000038 %|      0.000084 %|      0.000076| 0.75 vs  4.89  (ms)|0.15 | 42 | |InvSqrt     |[      0.0,  10000.0]|  0.000026 %|      0.000062 %|      0.000183| 0.94 vs  4.01  (ms)|0.23 | 43 | |Exp         |[    -20.0,     20.0]|  0.001698 %|      0.050661 %|  19760.000000| 5.55 vs  6.32  (ms)|0.88 | 44 | |Pow2        |[    -30.0,     30.0]|  0.001820 %|      0.050354 %|  72448.000000| 1.99 vs  5.39  (ms)|0.37 | 45 | |Log_e       |[      0.0,  10000.0]|  0.001206 %|     86.225453 %|      0.000031| 1.91 vs  3.28  (ms)|0.58 | 46 | |Log_2       |[      0.0,  10000.0]|  0.001206 %|     86.225884 %|      0.000043| 1.96 vs  2.89  (ms)|0.68 | 47 | |Log_10      |[      0.0,  10000.0]|  0.001206 %|     86.224927 %|      0.000013| 2.01 vs  3.37  (ms)|0.60 | 48 | |Pow(1.7,x)  |[    -30.0,     30.0]|  0.003043 %|      0.049457 %|   2121.500000| 4.64 vs 13.60  (ms)|0.34 | 49 | |Pow(x,1.7)  |[      0.6,     20.0]|  0.006763 %|      0.055199 %|      0.015121| 4.71 vs 14.78  (ms)|0.32 | 50 | |Fmod(x,1.7) |[ -10000.0,  10000.0]|  0.129491 %|   7214.285714 %|      1.700575|15.72 vs 11.69  (ms)|**1.34** | 51 | |Fmod(1.7,x) |[ -10000.0,  10000.0]|  0.000327 %|     15.789474 %|      0.000000| 4.46 vs  5.71  (ms)|0.78 | 52 | -------------------------------------------------------------------------------- /Test_BenchMark_Win_5950X.md: -------------------------------------------------------------------------------- 1 | # GFloat Test And BenchMark 2 | * Test time : Wed Nov 16 16:07:10 2022 3 | 4 | |Operation System| C++ Compiler version |CPU | Base Frequency | 5 | |:--:|:--:|:--:|:--:| 6 | |Windows 64-bit|Visual Studio :1932|AMD Ryzen 9 5950X 16-Core Processor |3.39 GHz or 0 GHz | 7 | * Performance: float vs GFloat, Call 1000000 times 8 | * Error : the relative error between cmath (double) and GFloat Math 9 | 10 | | Function | input data range |avg relative error | max relative error | max abs error | float vs GFloat | float / GFloat | 11 | |:--|:--:|:--:|:--:|:--:|:--:|:--:| 12 | |Mul+Add |[ -10000.0, 10000.0]| 0.000029 %| 4.347826 %| 32.000000| 0.53 vs 6.81 (ms)|0.08 | 13 | |Add |[ -10000.0, 10000.0]| 0.000004 %| 0.000024 %| 0.003906| 0.51 vs 6.10 (ms)|0.08 | 14 | |Sub |[ -10000.0, 10000.0]| 0.000004 %| 0.000024 %| 0.003906| 0.91 vs 8.80 (ms)|0.10 | 15 | |Mul |[ -10000.0, 10000.0]| 0.000009 %| 0.000024 %| 16.000000| 0.67 vs 2.82 (ms)|0.24 | 16 | |Div |[ -10000.0, 10000.0]| 0.000009 %| 0.000024 %| 0.031250| 0.88 vs 3.17 (ms)|0.28 | 17 | |Ceil |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 6.42 vs 3.52 (ms)|**1.82** | 18 | |Floor |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 6.28 vs 1.94 (ms)|**3.24** | 19 | |Whole |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.67 vs 5.27 (ms)|0.13 | 20 | |WholeFrac |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.44 vs 10.12 (ms)|0.04 | 21 | |Fraction |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.45 vs 5.89 (ms)|0.08 | 22 | |-() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.37 vs 1.93 (ms)|0.19 | 23 | |>() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.50 vs 3.95 (ms)|0.13 | 24 | |<() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.50 vs 8.83 (ms)|0.06 | 25 | |>=() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.49 vs 8.65 (ms)|0.06 | 26 | |<=() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.57 vs 5.09 (ms)|0.11 | 27 | |Abs |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.40 vs 4.64 (ms)|0.09 | 28 | |Normalize32 |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.41 vs 1.88 (ms)|0.22 | 29 | |Normalize64 |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.39 vs 1.96 (ms)|0.20 | 30 | |FromInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.51 vs 2.01 (ms)|0.25 | 31 | |Fromfloat |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.39 vs 0.62 (ms)|0.62 | 32 | |CeilToInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 6.42 vs 3.36 (ms)|**1.91** | 33 | |FloorToInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 6.25 vs 3.10 (ms)|**2.02** | 34 | |Sin |[ -10000.0, 10000.0]| 0.000099 %| 4.559921 %| 0.000005| 9.37 vs 8.99 (ms)|**1.04** | 35 | |Cos |[ -10000.0, 10000.0]| 0.001805 %| 0.122642 %| 0.000028| 9.23 vs 10.18 (ms)|0.91 | 36 | |Tan |[ -10000.0, 10000.0]| 0.001776 %| 4.562861 %| 83.726562| 8.84 vs 20.49 (ms)|0.43 | 37 | |ASin |[ -1.0, 1.0]| 0.031373 %| 100.000000 %| 0.049958| 8.09 vs 15.70 (ms)|0.52 | 38 | |ACos |[ -1.0, 1.0]| 0.117627 %| 98.413861 %| 0.049958| 7.80 vs 26.50 (ms)|0.29 | 39 | |ATan |[ -10000.0, 10000.0]| 0.003567 %| 0.036536 %| 0.000166| 8.79 vs 23.00 (ms)|0.38 | 40 | |ATan(10,x) |[ -10000.0, 10000.0]| 0.006190 %| 0.021383 %| 0.000166|11.22 vs 27.85 (ms)|0.40 | 41 | |ATan(x,10) |[ -10000.0, 10000.0]| 0.007318 %| 0.230349 %| 0.000166|11.46 vs 26.37 (ms)|0.43 | 42 | |Sqrt |[ 0.0, 10000.0]| 0.000034 %| 0.000072 %| 0.000061| 1.14 vs 19.29 (ms)|0.06 | 43 | |InvSqrt |[ 0.0, 10000.0]| 0.000026 %| 0.000062 %| 0.000183| 1.91 vs 14.25 (ms)|0.13 | 44 | |Exp |[ -20.0, 20.0]| 0.001689 %| 0.050400 %| 19056.000000| 2.34 vs 13.64 (ms)|0.17 | 45 | |Pow2 |[ -30.0, 30.0]| 0.001820 %| 0.050354 %| 72448.000000| 6.42 vs 9.00 (ms)|0.71 | 46 | |Log_e |[ 0.0, 10000.0]| 0.001206 %| 86.225453 %| 0.000031| 3.12 vs 5.97 (ms)|0.52 | 47 | |Log_2 |[ 0.0, 10000.0]| 0.001206 %| 86.225884 %| 0.000043|24.27 vs 5.67 (ms)|**4.28** | 48 | |Log_10 |[ 0.0, 10000.0]| 0.001206 %| 86.224927 %| 0.000013| 3.33 vs 6.06 (ms)|0.55 | 49 | |Pow(1.7,x) |[ -30.0, 30.0]| 0.003042 %| 0.049457 %| 2121.500000| 6.42 vs 33.01 (ms)|0.19 | 50 | |Pow(x,1.7) |[ 0.6, 20.0]| 0.006756 %| 0.055199 %| 0.015030| 6.84 vs 29.47 (ms)|0.23 | 51 | |Fmod(x,1.7) |[ -10000.0, 10000.0]| 0.126278 %| 7214.285714 %| 1.700552|13.01 vs 26.47 (ms)|0.49 | 52 | |Fmod(1.7,x) |[ -10000.0, 10000.0]| 0.000381 %| 15.789474 %| 0.000000| 5.76 vs 14.26 (ms)|0.40 | 53 | -------------------------------------------------------------------------------- /Test_BenchMark_Android_S9_Snapdragon845.md: -------------------------------------------------------------------------------- 1 | 2022-10-21 11:34:11.537 2065-2065/? I/GFloat: # GFloat Test And BenchMark 2 | * Test time : Fri Oct 21 11:34:11 2022 3 | 4 | |Operation System| C++ Compiler version |CPU | Base Frequency | 5 | |:--:|:--:|:--:|:--:| 6 | |Android|4.2.1 Compatible Android (5900059 based on r365631c) Clang 9.0.8 (https://android.googlesource.com/toolchain/llvm-project 207d7abc1a2abf3ef8d4301736d6a7ebc224a290)|Unkown CPU|0.0192 GHz or 0.019 GHz | 7 | * Performance: float vs GFloat, Call 1000000 times 8 | * Error : the relative error between cmath (double) and GFloat Math 9 | 10 | | Function | input data range |avg relative error | max relative error | max abs error |float vs GFloat | float / GFloat | 11 | |:--|:--:|:--:|:--:|:--:|:--:|:--:| 12 | |Add |[ -10000.0, 10000.0]| 0.000004 %| 0.000024 %| 0.003906| 1.10 vs 12.29 (ms)|0.09 | 13 | |Sub |[ -10000.0, 10000.0]| 0.000004 %| 0.000024 %| 0.003906| 0.95 vs 12.82 (ms)|0.07 | 14 | |Mul |[ -10000.0, 10000.0]| 0.000012 %| 0.000048 %| 32.000000| 0.96 vs 3.87 (ms)|0.25 | 15 | |Div |[ -10000.0, 10000.0]| 0.000009 %| 0.000024 %| 0.031250| 1.55 vs 9.12 (ms)|0.17 | 16 | |Ceil |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.54 vs 8.07 (ms)|0.07 | 17 | |Floor |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.52 vs 3.62 (ms)|0.14 | 18 | |Whole |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.63 vs 6.81 (ms)|0.09 | 19 | |WholeFrac |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.52 vs 17.66 (ms)|0.03 | 20 | |Fraction |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.62 vs 7.24 (ms)|0.09 | 21 | |-() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.52 vs 3.38 (ms)|0.15 | 22 | |>() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.92 vs 8.81 (ms)|0.10 | 23 | |<() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.93 vs 9.27 (ms)|0.10 | 24 | |>=() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.85 vs 9.19 (ms)|0.09 | 25 | |<=() |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.84 vs 6.43 (ms)|0.13 | 26 | |Abs |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.51 vs 6.88 (ms)|0.07 | 27 | |Normalize32 |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.57 vs 4.45 (ms)|0.13 | 28 | |Normalize64 |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.50 vs 4.83 (ms)|0.10 | 29 | |FromInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.62 vs 3.22 (ms)|0.19 | 30 | |Fromfloat |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.60 vs 0.47 (ms)|**1.28** | 31 | |CeilToInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.51 vs 5.64 (ms)|0.09 | 32 | |FloorToInt |[ -10000.0, 10000.0]| 0.000000 %| 0.000000 %| 0.000000| 0.51 vs 5.29 (ms)|0.10 | 33 | |Sin |[ -10000.0, 10000.0]| 0.000099 %| 4.559921 %| 0.000005|14.02 vs 25.86 (ms)|0.54 | 34 | |Cos |[ -10000.0, 10000.0]| 0.001805 %| 0.122642 %| 0.000028|13.80 vs 24.90 (ms)|0.55 | 35 | |Tan |[ -10000.0, 10000.0]| 0.001776 %| 4.562861 %| 83.726562|16.53 vs 56.95 (ms)|0.29 | 36 | |ASin |[ -1.0, 1.0]| 0.031373 %| 100.000000 %| 0.049958| 6.95 vs 42.52 (ms)|0.16 | 37 | |ACos |[ -1.0, 1.0]| 0.117627 %| 98.413861 %| 0.049958| 7.04 vs 55.20 (ms)|0.13 | 38 | |ATan |[ -10000.0, 10000.0]| 0.003567 %| 0.036536 %| 0.000166|13.98 vs 41.97 (ms)|0.33 | 39 | |ATan(10,x) |[ -10000.0, 10000.0]| 0.006189 %| 0.021383 %| 0.000166|22.51 vs 54.09 (ms)|0.42 | 40 | |ATan(x,10) |[ -10000.0, 10000.0]| 0.007318 %| 0.230349 %| 0.000166|20.99 vs 52.51 (ms)|0.40 | 41 | |Sqrt |[ 0.0, 10000.0]| 0.000038 %| 0.000084 %| 0.000076| 1.75 vs 25.82 (ms)|0.07 | 42 | |InvSqrt |[ 0.0, 10000.0]| 0.000026 %| 0.000062 %| 0.000183| 3.02 vs 23.11 (ms)|0.13 | 43 | |Exp |[ -20.0, 20.0]| 0.001698 %| 0.050661 %| 19760.000000| 6.92 vs 31.68 (ms)|0.22 | 44 | |Pow2 |[ -30.0, 30.0]| 0.001820 %| 0.050354 %| 72448.000000| 7.28 vs 30.62 (ms)|0.24 | 45 | |Log_e |[ 0.0, 10000.0]| 0.001206 %| 86.225453 %| 0.000031| 6.71 vs 20.06 (ms)|0.33 | 46 | |Log_2 |[ 0.0, 10000.0]| 0.001206 %| 86.225898 %| 0.000043| 6.81 vs 18.92 (ms)|0.36 | 47 | |Log_10 |[ 0.0, 10000.0]| 0.001206 %| 86.224927 %| 0.000013|18.76 vs 20.10 (ms)|0.93 | 48 | |Pow(1.7,x) |[ -30.0, 30.0]| 0.003043 %| 0.049457 %| 2121.500000|17.21 vs 50.38 (ms)|0.34 | 49 | |Pow(x,1.7) |[ 0.6, 20.0]| 0.006763 %| 0.055199 %| 0.015121|17.04 vs 55.49 (ms)|0.31 | 50 | |Fmod(x,1.7) |[ -10000.0, 10000.0]| 0.129491 %| 7214.285714 %| 1.700575|32.77 vs 30.06 (ms)|**1.09** | 51 | |Fmod(1.7,x) |[ -10000.0, 10000.0]| 0.000327 %| 15.789474 %| 0.000000|10.75 vs 19.99 (ms)|0.54 | 52 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_win/deterministic_float.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {c940a429-f527-4415-8b80-143dab3dcd69} 25 | deterministicfloat 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v143 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | 92 | 93 | Console 94 | true 95 | 96 | 97 | 98 | 99 | Level3 100 | true 101 | true 102 | true 103 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | 106 | 107 | Console 108 | true 109 | true 110 | true 111 | 112 | 113 | 114 | 115 | Level4 116 | true 117 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | stdcpp14 120 | 121 | 122 | Console 123 | true 124 | 125 | 126 | 127 | 128 | Level3 129 | true 130 | true 131 | true 132 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 133 | true 134 | StreamingSIMDExtensions2 135 | 136 | 137 | Console 138 | true 139 | true 140 | true 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /deterministic/glacier_platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 zhou xuan, Email: zhouxuan6676@gmail.com 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at * 6 | * http://www.apache.org/licenses/LICENSE-2.0 * 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | #pragma once 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #ifdef _MSC_VER 25 | #include 26 | #endif 27 | 28 | #ifdef __APPLE__ 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #endif 35 | 36 | #ifdef __ANDROID__ 37 | #include 38 | #include 39 | #endif 40 | 41 | #if defined(_MSC_VER) || (defined(__GNUC__)) 42 | #define UseProfiler_RDTSCP 1 43 | #endif 44 | 45 | 46 | #define __PRINT_MARCO(x) #x 47 | #define PRINT_MARCO(x) #x"=" __PRINT_MARCO(x) 48 | 49 | #pragma message(PRINT_MARCO(UseProfiler_RDTSCP)) 50 | #pragma message(PRINT_MARCO(__ARM_ARCH)) 51 | #pragma message(PRINT_MARCO(__ANDROID_API__)) 52 | 53 | std::string getOSName() 54 | { 55 | #if defined(_WIN32) && !defined(_WIN64) 56 | return "Windows 32-bit"; 57 | #elif _WIN64 58 | return "Windows 64-bit"; 59 | #elif __APPLE__ || __MACH__ 60 | utsname systeminfo; 61 | uname(&systeminfo); 62 | 63 | return systeminfo.sysname; 64 | 65 | #elif __ANDROID__ 66 | return "Android"; 67 | #elif __linux__ 68 | return "Linux"; 69 | #elif __FreeBSD__ 70 | return "FreeBSD"; 71 | #elif __unix || __unix__ 72 | return "Unix"; 73 | #else 74 | return "Other"; 75 | #endif 76 | } 77 | 78 | 79 | std::string GetCompileName() 80 | { 81 | #if defined(_MSC_VER) 82 | return "Visual Studio :" + std::to_string(_MSC_VER); 83 | #elif __GNUC__ 84 | return __VERSION__; 85 | #else 86 | return "Unkown Compile"; 87 | #endif 88 | } 89 | 90 | std::string GetCpuName() 91 | { 92 | #if defined(_MSC_VER) 93 | std::array cpui; 94 | std::vector> extdata_; 95 | __cpuid(cpui.data(), 0x80000000); 96 | int nExIds_ = cpui[0]; 97 | 98 | char brand[0x40]; 99 | memset(brand, 0, sizeof(brand)); 100 | 101 | for (int i = 0x80000000; i <= nExIds_; ++i) 102 | { 103 | __cpuidex(cpui.data(), i, 0); 104 | extdata_.push_back(cpui); 105 | } 106 | 107 | std::string brand_; 108 | 109 | // Interpret CPU brand string if reported 110 | if (nExIds_ >= 0x80000004) 111 | { 112 | memcpy(brand, extdata_[2].data(), sizeof(cpui)); 113 | memcpy(brand + 16, extdata_[3].data(), sizeof(cpui)); 114 | memcpy(brand + 32, extdata_[4].data(), sizeof(cpui)); 115 | brand_ = brand; 116 | } 117 | 118 | return brand_; 119 | #elif __APPLE__ 120 | 121 | size_t size; 122 | cpu_type_t type; 123 | cpu_subtype_t subtype; 124 | size = sizeof(type); 125 | sysctlbyname("hw.cputype", &type, &size, NULL, 0); 126 | 127 | size = sizeof(subtype); 128 | sysctlbyname("hw.cpusubtype", &subtype, &size, NULL, 0); 129 | 130 | std::string TS = "Apple "; 131 | 132 | utsname systeminfo; 133 | uname(&systeminfo); 134 | 135 | TS += systeminfo.machine; 136 | 137 | TS += " Arch : "; 138 | 139 | if (type == CPU_TYPE_X86_64) { 140 | TS+="x86_64"; 141 | } else if (type == CPU_TYPE_X86) { 142 | TS+="x86"; 143 | } else if (type == CPU_TYPE_ARM) { 144 | TS+="ARM_"; 145 | switch(subtype) 146 | { 147 | case CPU_SUBTYPE_ARM_V6: 148 | TS+="V6"; 149 | break; 150 | case CPU_SUBTYPE_ARM_V7: 151 | TS+="V7"; 152 | break; 153 | case CPU_SUBTYPE_ARM_V8: 154 | TS+="V8"; 155 | break; 156 | } 157 | } 158 | else if (type == CPU_TYPE_ARM64) { 159 | TS+="ARM64_"; 160 | switch(subtype) 161 | { 162 | case CPU_SUBTYPE_ARM64_V8: 163 | TS+="V8"; 164 | break; 165 | case CPU_SUBTYPE_ARM64E: 166 | TS+="E"; 167 | break; 168 | } 169 | } 170 | 171 | //char buffer[1024]; 172 | // size=sizeof(buffer); 173 | //if (sysctlbyname("machdep.cpu.brand_string", &buffer, &size, NULL, 0) < 0) { 174 | // perror("sysctl"); 175 | //} 176 | //std::cout << buffer << '\n'; 177 | //TS += " : " + std::string(buffer); 178 | 179 | 180 | return TS.c_str(); 181 | #elif __ANDROID__ 182 | 183 | 184 | /*std::vector> properties; 185 | __system_property_foreach( 186 | [](const prop_info* pi, void* cookie) { 187 | __system_property_read_callback( 188 | pi, 189 | [](void* cookie, const char* name, const char* value, unsigned) { 190 | auto properties = reinterpret_cast>*>(cookie); 191 | properties->emplace_back(name, value); 192 | }, 193 | cookie); 194 | }, 195 | &properties);*/ 196 | 197 | //std::sort(properties.begin(), properties.end()); 198 | 199 | 200 | char buffer[1024]; 201 | __system_property_get("os.Build.BRAND", buffer ); 202 | return std::string(buffer); 203 | 204 | 205 | 206 | 207 | #else 208 | 209 | 210 | 211 | return "Unkown CPU"; 212 | #endif 213 | } 214 | 215 | typedef std::chrono::high_resolution_clock Myclock; 216 | typedef std::chrono::nanoseconds Myres; 217 | 218 | class GTimer 219 | { 220 | public: 221 | GTimer() 222 | #if UseProfiler_RDTSCP 223 | : start_(0), end_(0) 224 | #else 225 | : t1(Myres::zero()), t2(Myres::zero()) 226 | #endif 227 | { 228 | Start(); 229 | } 230 | 231 | ~GTimer() 232 | {} 233 | 234 | static inline uint64_t get_CPUCycles() 235 | { 236 | #ifdef _MSC_VER 237 | return __rdtsc(); 238 | #elif __GNUC__ 239 | 240 | #if defined(__x86_64__) 241 | 242 | unsigned int lo, hi; 243 | __asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi)); 244 | return ((uint64_t)hi << 32) | lo; 245 | 246 | #elif defined(__aarch64__) 247 | 248 | uint64_t virtual_timer_value; 249 | asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value)); 250 | return virtual_timer_value; 251 | 252 | #else 253 | return 0; 254 | #endif 255 | 256 | #else 257 | return 0; 258 | #endif 259 | } 260 | 261 | void Start() 262 | { 263 | #if UseProfiler_RDTSCP 264 | start_ = get_CPUCycles(); 265 | #else 266 | t1 = Myclock::now(); 267 | #endif 268 | } 269 | 270 | void End() 271 | { 272 | #if UseProfiler_RDTSCP 273 | end_ = get_CPUCycles(); 274 | #else 275 | t2 = Myclock::now(); 276 | #endif 277 | } 278 | 279 | 280 | float GetDeltaTimeMS_NoEnd() 281 | { 282 | #if UseProfiler_RDTSCP 283 | return float(double(end_ - start_) * InvCPUGHZ); 284 | #else 285 | return float(std::chrono::duration_cast(t2 - t1).count() * 1e-6); 286 | #endif 287 | } 288 | 289 | float GetDeltaTimeMS() 290 | { 291 | End(); 292 | return GetDeltaTimeMS_NoEnd(); 293 | } 294 | 295 | static double GetCpuFrequency_Compute() 296 | { 297 | #if UseProfiler_RDTSCP 298 | return 1 / InvCPUGHZ; 299 | #else 300 | return 0; 301 | #endif 302 | } 303 | 304 | #if defined(__GNUC__) && defined(__x86_64__) && !defined(__aarch64__) 305 | #include 306 | #endif 307 | 308 | static int GetCpuFrequency_CpuInfo() 309 | { 310 | int cpuInfo[4] = { 0, 0, 0, 0 }; 311 | #ifdef _MSC_VER 312 | __cpuid(cpuInfo, 0); 313 | if (cpuInfo[0] >= 0x16) { 314 | __cpuid(cpuInfo, 0x16); 315 | return cpuInfo[0]; 316 | } 317 | #elif __GNUC__ 318 | 319 | #if defined(__x86_64__) && !defined(__aarch64__) 320 | 321 | __cpuid(0, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]); 322 | 323 | if (cpuInfo[0] >= 0x16) { 324 | __cpuid(0x16, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]); 325 | return cpuInfo[0]; 326 | } 327 | #elif defined(__ARM_ARCH) 328 | 329 | uint64_t freq; 330 | asm volatile("mrs %0, cntfrq_el0" : "=r" (freq)); 331 | return (int)(freq / 1000000); 332 | 333 | #endif 334 | 335 | #else 336 | 337 | #endif 338 | 339 | return 0; 340 | } 341 | 342 | private: 343 | 344 | #if UseProfiler_RDTSCP 345 | 346 | static double InvCPUGHZ; 347 | volatile uint64_t start_; 348 | volatile uint64_t end_; 349 | #else 350 | Myclock::time_point t1; 351 | Myclock::time_point t2; 352 | #endif 353 | 354 | }; 355 | 356 | void GPrintLog( const std::stringstream& STR ) 357 | { 358 | #if __ANDROID__ 359 | 360 | __android_log_print(ANDROID_LOG_INFO, "GFloat", "%s", STR.str().c_str()); 361 | 362 | #else 363 | 364 | std::cout << STR.str(); 365 | 366 | #endif 367 | } 368 | 369 | 370 | 371 | -------------------------------------------------------------------------------- /deterministic/deterministic_float.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FA38AAF528D07B2100ED6160 /* glacier_float.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA38AAF428D07B2100ED6160 /* glacier_float.cpp */; }; 11 | FA38AAF728D07B2900ED6160 /* deterministic_float.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA38AAF628D07B2900ED6160 /* deterministic_float.cpp */; }; 12 | FAAA1CA728D83E7200B5894F /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAAA1CA628D83E7200B5894F /* main.cpp */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | FA38AAE728D07A9200ED6160 /* CopyFiles */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 2147483647; 19 | dstPath = /usr/share/man/man1/; 20 | dstSubfolderSpec = 0; 21 | files = ( 22 | ); 23 | runOnlyForDeploymentPostprocessing = 1; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | FA38AAE928D07A9200ED6160 /* deterministic_float */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = deterministic_float; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | FA38AAF328D07B2100ED6160 /* glacier_float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glacier_float.h; sourceTree = ""; }; 30 | FA38AAF428D07B2100ED6160 /* glacier_float.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glacier_float.cpp; sourceTree = ""; }; 31 | FA38AAF628D07B2900ED6160 /* deterministic_float.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = deterministic_float.cpp; sourceTree = ""; }; 32 | FAAA1CA628D83E7200B5894F /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; 33 | FAAA1CA828D83E8000B5894F /* deterministic_float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = deterministic_float.h; sourceTree = ""; }; 34 | /* End PBXFileReference section */ 35 | 36 | /* Begin PBXFrameworksBuildPhase section */ 37 | FA38AAE628D07A9200ED6160 /* Frameworks */ = { 38 | isa = PBXFrameworksBuildPhase; 39 | buildActionMask = 2147483647; 40 | files = ( 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | /* End PBXFrameworksBuildPhase section */ 45 | 46 | /* Begin PBXGroup section */ 47 | FA38AAE028D07A9200ED6160 = { 48 | isa = PBXGroup; 49 | children = ( 50 | FA38AAF428D07B2100ED6160 /* glacier_float.cpp */, 51 | FA38AAF328D07B2100ED6160 /* glacier_float.h */, 52 | FA38AAF628D07B2900ED6160 /* deterministic_float.cpp */, 53 | FAAA1CA628D83E7200B5894F /* main.cpp */, 54 | FAAA1CA828D83E8000B5894F /* deterministic_float.h */, 55 | FA38AAEA28D07A9200ED6160 /* Products */, 56 | ); 57 | sourceTree = ""; 58 | }; 59 | FA38AAEA28D07A9200ED6160 /* Products */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | FA38AAE928D07A9200ED6160 /* deterministic_float */, 63 | ); 64 | name = Products; 65 | sourceTree = ""; 66 | }; 67 | /* End PBXGroup section */ 68 | 69 | /* Begin PBXNativeTarget section */ 70 | FA38AAE828D07A9200ED6160 /* deterministic_float */ = { 71 | isa = PBXNativeTarget; 72 | buildConfigurationList = FA38AAF028D07A9200ED6160 /* Build configuration list for PBXNativeTarget "deterministic_float" */; 73 | buildPhases = ( 74 | FA38AAE528D07A9200ED6160 /* Sources */, 75 | FA38AAE628D07A9200ED6160 /* Frameworks */, 76 | FA38AAE728D07A9200ED6160 /* CopyFiles */, 77 | ); 78 | buildRules = ( 79 | ); 80 | dependencies = ( 81 | ); 82 | name = deterministic_float; 83 | productName = deterministic_float; 84 | productReference = FA38AAE928D07A9200ED6160 /* deterministic_float */; 85 | productType = "com.apple.product-type.tool"; 86 | }; 87 | /* End PBXNativeTarget section */ 88 | 89 | /* Begin PBXProject section */ 90 | FA38AAE128D07A9200ED6160 /* Project object */ = { 91 | isa = PBXProject; 92 | attributes = { 93 | BuildIndependentTargetsInParallel = 1; 94 | LastUpgradeCheck = 1340; 95 | TargetAttributes = { 96 | FA38AAE828D07A9200ED6160 = { 97 | CreatedOnToolsVersion = 13.4; 98 | }; 99 | }; 100 | }; 101 | buildConfigurationList = FA38AAE428D07A9200ED6160 /* Build configuration list for PBXProject "deterministic_float" */; 102 | compatibilityVersion = "Xcode 13.0"; 103 | developmentRegion = en; 104 | hasScannedForEncodings = 0; 105 | knownRegions = ( 106 | en, 107 | Base, 108 | ); 109 | mainGroup = FA38AAE028D07A9200ED6160; 110 | productRefGroup = FA38AAEA28D07A9200ED6160 /* Products */; 111 | projectDirPath = ""; 112 | projectRoot = ""; 113 | targets = ( 114 | FA38AAE828D07A9200ED6160 /* deterministic_float */, 115 | ); 116 | }; 117 | /* End PBXProject section */ 118 | 119 | /* Begin PBXSourcesBuildPhase section */ 120 | FA38AAE528D07A9200ED6160 /* Sources */ = { 121 | isa = PBXSourcesBuildPhase; 122 | buildActionMask = 2147483647; 123 | files = ( 124 | FA38AAF528D07B2100ED6160 /* glacier_float.cpp in Sources */, 125 | FA38AAF728D07B2900ED6160 /* deterministic_float.cpp in Sources */, 126 | FAAA1CA728D83E7200B5894F /* main.cpp in Sources */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXSourcesBuildPhase section */ 131 | 132 | /* Begin XCBuildConfiguration section */ 133 | FA38AAEE28D07A9200ED6160 /* Debug */ = { 134 | isa = XCBuildConfiguration; 135 | buildSettings = { 136 | ALWAYS_SEARCH_USER_PATHS = NO; 137 | CLANG_ANALYZER_NONNULL = YES; 138 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 139 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 140 | CLANG_ENABLE_MODULES = YES; 141 | CLANG_ENABLE_OBJC_ARC = YES; 142 | CLANG_ENABLE_OBJC_WEAK = YES; 143 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 144 | CLANG_WARN_BOOL_CONVERSION = YES; 145 | CLANG_WARN_COMMA = YES; 146 | CLANG_WARN_CONSTANT_CONVERSION = YES; 147 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 148 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 149 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 150 | CLANG_WARN_EMPTY_BODY = YES; 151 | CLANG_WARN_ENUM_CONVERSION = YES; 152 | CLANG_WARN_INFINITE_RECURSION = YES; 153 | CLANG_WARN_INT_CONVERSION = YES; 154 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 155 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 156 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 157 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 158 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 159 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 160 | CLANG_WARN_STRICT_PROTOTYPES = YES; 161 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 162 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 163 | CLANG_WARN_UNREACHABLE_CODE = YES; 164 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 165 | COPY_PHASE_STRIP = NO; 166 | DEBUG_INFORMATION_FORMAT = dwarf; 167 | ENABLE_STRICT_OBJC_MSGSEND = YES; 168 | ENABLE_TESTABILITY = YES; 169 | GCC_C_LANGUAGE_STANDARD = gnu11; 170 | GCC_DYNAMIC_NO_PIC = NO; 171 | GCC_NO_COMMON_BLOCKS = YES; 172 | GCC_OPTIMIZATION_LEVEL = 0; 173 | GCC_PREPROCESSOR_DEFINITIONS = ( 174 | "DEBUG=1", 175 | "$(inherited)", 176 | ); 177 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 178 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 179 | GCC_WARN_UNDECLARED_SELECTOR = YES; 180 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 181 | GCC_WARN_UNUSED_FUNCTION = YES; 182 | GCC_WARN_UNUSED_VARIABLE = YES; 183 | MACOSX_DEPLOYMENT_TARGET = 12.0; 184 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 185 | MTL_FAST_MATH = YES; 186 | ONLY_ACTIVE_ARCH = YES; 187 | SDKROOT = macosx; 188 | }; 189 | name = Debug; 190 | }; 191 | FA38AAEF28D07A9200ED6160 /* Release */ = { 192 | isa = XCBuildConfiguration; 193 | buildSettings = { 194 | ALWAYS_SEARCH_USER_PATHS = NO; 195 | CLANG_ANALYZER_NONNULL = YES; 196 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 197 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 198 | CLANG_ENABLE_MODULES = YES; 199 | CLANG_ENABLE_OBJC_ARC = YES; 200 | CLANG_ENABLE_OBJC_WEAK = YES; 201 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 202 | CLANG_WARN_BOOL_CONVERSION = YES; 203 | CLANG_WARN_COMMA = YES; 204 | CLANG_WARN_CONSTANT_CONVERSION = YES; 205 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 206 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 207 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 208 | CLANG_WARN_EMPTY_BODY = YES; 209 | CLANG_WARN_ENUM_CONVERSION = YES; 210 | CLANG_WARN_INFINITE_RECURSION = YES; 211 | CLANG_WARN_INT_CONVERSION = YES; 212 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 213 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 214 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 215 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 216 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 217 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 218 | CLANG_WARN_STRICT_PROTOTYPES = YES; 219 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 220 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 221 | CLANG_WARN_UNREACHABLE_CODE = YES; 222 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 223 | COPY_PHASE_STRIP = NO; 224 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 225 | ENABLE_NS_ASSERTIONS = NO; 226 | ENABLE_STRICT_OBJC_MSGSEND = YES; 227 | GCC_C_LANGUAGE_STANDARD = gnu11; 228 | GCC_NO_COMMON_BLOCKS = YES; 229 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 230 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 231 | GCC_WARN_UNDECLARED_SELECTOR = YES; 232 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 233 | GCC_WARN_UNUSED_FUNCTION = YES; 234 | GCC_WARN_UNUSED_VARIABLE = YES; 235 | MACOSX_DEPLOYMENT_TARGET = 12.0; 236 | MTL_ENABLE_DEBUG_INFO = NO; 237 | MTL_FAST_MATH = YES; 238 | SDKROOT = macosx; 239 | }; 240 | name = Release; 241 | }; 242 | FA38AAF128D07A9200ED6160 /* Debug */ = { 243 | isa = XCBuildConfiguration; 244 | buildSettings = { 245 | CODE_SIGN_STYLE = Automatic; 246 | DEVELOPMENT_TEAM = 7425H6FX5M; 247 | ENABLE_HARDENED_RUNTIME = YES; 248 | PRODUCT_NAME = "$(TARGET_NAME)"; 249 | }; 250 | name = Debug; 251 | }; 252 | FA38AAF228D07A9200ED6160 /* Release */ = { 253 | isa = XCBuildConfiguration; 254 | buildSettings = { 255 | CODE_SIGN_STYLE = Automatic; 256 | DEVELOPMENT_TEAM = 7425H6FX5M; 257 | ENABLE_HARDENED_RUNTIME = YES; 258 | PRODUCT_NAME = "$(TARGET_NAME)"; 259 | }; 260 | name = Release; 261 | }; 262 | /* End XCBuildConfiguration section */ 263 | 264 | /* Begin XCConfigurationList section */ 265 | FA38AAE428D07A9200ED6160 /* Build configuration list for PBXProject "deterministic_float" */ = { 266 | isa = XCConfigurationList; 267 | buildConfigurations = ( 268 | FA38AAEE28D07A9200ED6160 /* Debug */, 269 | FA38AAEF28D07A9200ED6160 /* Release */, 270 | ); 271 | defaultConfigurationIsVisible = 0; 272 | defaultConfigurationName = Release; 273 | }; 274 | FA38AAF028D07A9200ED6160 /* Build configuration list for PBXNativeTarget "deterministic_float" */ = { 275 | isa = XCConfigurationList; 276 | buildConfigurations = ( 277 | FA38AAF128D07A9200ED6160 /* Debug */, 278 | FA38AAF228D07A9200ED6160 /* Release */, 279 | ); 280 | defaultConfigurationIsVisible = 0; 281 | defaultConfigurationName = Release; 282 | }; 283 | /* End XCConfigurationList section */ 284 | }; 285 | rootObject = FA38AAE128D07A9200ED6160 /* Project object */; 286 | } 287 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [zhou xuan] [Email:zhouxuan6676@gmail.com] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /deterministic/deterministic_float_ios.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FA2263BA28D455E300FEE0CA /* glacier_float.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA2263B928D455E300FEE0CA /* glacier_float.cpp */; }; 11 | FA2263BC28D455FA00FEE0CA /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA2263BB28D455FA00FEE0CA /* main.mm */; }; 12 | FA2263C028D4560500FEE0CA /* glacier_float.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA2263BE28D4560500FEE0CA /* glacier_float.cpp */; }; 13 | FA2263C228D4560F00FEE0CA /* deterministic_float.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA2263C128D4560F00FEE0CA /* deterministic_float.cpp */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXFileReference section */ 17 | FA22637F28D4558E00FEE0CA /* deterministic_float_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = deterministic_float_ios.app; sourceTree = BUILT_PRODUCTS_DIR; }; 18 | FA2263B928D455E300FEE0CA /* glacier_float.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glacier_float.cpp; sourceTree = ""; }; 19 | FA2263BB28D455FA00FEE0CA /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; 20 | FA2263BD28D4560500FEE0CA /* glacier_float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glacier_float.h; sourceTree = ""; }; 21 | FA2263BE28D4560500FEE0CA /* glacier_float.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glacier_float.cpp; sourceTree = ""; }; 22 | FA2263BF28D4560500FEE0CA /* deterministic_float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = deterministic_float.h; sourceTree = ""; }; 23 | FA2263C128D4560F00FEE0CA /* deterministic_float.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = deterministic_float.cpp; sourceTree = ""; }; 24 | /* End PBXFileReference section */ 25 | 26 | /* Begin PBXFrameworksBuildPhase section */ 27 | FA22637C28D4558E00FEE0CA /* Frameworks */ = { 28 | isa = PBXFrameworksBuildPhase; 29 | buildActionMask = 2147483647; 30 | files = ( 31 | ); 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | /* End PBXFrameworksBuildPhase section */ 35 | 36 | /* Begin PBXGroup section */ 37 | FA22637628D4558E00FEE0CA = { 38 | isa = PBXGroup; 39 | children = ( 40 | FA2263BF28D4560500FEE0CA /* deterministic_float.h */, 41 | FA2263B928D455E300FEE0CA /* glacier_float.cpp */, 42 | FA2263BB28D455FA00FEE0CA /* main.mm */, 43 | FA2263BE28D4560500FEE0CA /* glacier_float.cpp */, 44 | FA2263BD28D4560500FEE0CA /* glacier_float.h */, 45 | FA2263C128D4560F00FEE0CA /* deterministic_float.cpp */, 46 | FA22638028D4558E00FEE0CA /* Products */, 47 | ); 48 | sourceTree = ""; 49 | }; 50 | FA22638028D4558E00FEE0CA /* Products */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | FA22637F28D4558E00FEE0CA /* deterministic_float_ios.app */, 54 | ); 55 | name = Products; 56 | sourceTree = ""; 57 | }; 58 | /* End PBXGroup section */ 59 | 60 | /* Begin PBXNativeTarget section */ 61 | FA22637E28D4558E00FEE0CA /* deterministic_float_ios */ = { 62 | isa = PBXNativeTarget; 63 | buildConfigurationList = FA2263B028D4558E00FEE0CA /* Build configuration list for PBXNativeTarget "deterministic_float_ios" */; 64 | buildPhases = ( 65 | FA22637B28D4558E00FEE0CA /* Sources */, 66 | FA22637C28D4558E00FEE0CA /* Frameworks */, 67 | FA22637D28D4558E00FEE0CA /* Resources */, 68 | ); 69 | buildRules = ( 70 | ); 71 | dependencies = ( 72 | ); 73 | name = deterministic_float_ios; 74 | productName = deterministic_float_ios; 75 | productReference = FA22637F28D4558E00FEE0CA /* deterministic_float_ios.app */; 76 | productType = "com.apple.product-type.application"; 77 | }; 78 | /* End PBXNativeTarget section */ 79 | 80 | /* Begin PBXProject section */ 81 | FA22637728D4558E00FEE0CA /* Project object */ = { 82 | isa = PBXProject; 83 | attributes = { 84 | BuildIndependentTargetsInParallel = 1; 85 | LastUpgradeCheck = 1340; 86 | TargetAttributes = { 87 | FA22637E28D4558E00FEE0CA = { 88 | CreatedOnToolsVersion = 13.4; 89 | }; 90 | }; 91 | }; 92 | buildConfigurationList = FA22637A28D4558E00FEE0CA /* Build configuration list for PBXProject "deterministic_float_ios" */; 93 | compatibilityVersion = "Xcode 13.0"; 94 | developmentRegion = en; 95 | hasScannedForEncodings = 0; 96 | knownRegions = ( 97 | en, 98 | Base, 99 | ); 100 | mainGroup = FA22637628D4558E00FEE0CA; 101 | productRefGroup = FA22638028D4558E00FEE0CA /* Products */; 102 | projectDirPath = ""; 103 | projectRoot = ""; 104 | targets = ( 105 | FA22637E28D4558E00FEE0CA /* deterministic_float_ios */, 106 | ); 107 | }; 108 | /* End PBXProject section */ 109 | 110 | /* Begin PBXResourcesBuildPhase section */ 111 | FA22637D28D4558E00FEE0CA /* Resources */ = { 112 | isa = PBXResourcesBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | ); 116 | runOnlyForDeploymentPostprocessing = 0; 117 | }; 118 | /* End PBXResourcesBuildPhase section */ 119 | 120 | /* Begin PBXSourcesBuildPhase section */ 121 | FA22637B28D4558E00FEE0CA /* Sources */ = { 122 | isa = PBXSourcesBuildPhase; 123 | buildActionMask = 2147483647; 124 | files = ( 125 | FA2263BC28D455FA00FEE0CA /* main.mm in Sources */, 126 | FA2263C228D4560F00FEE0CA /* deterministic_float.cpp in Sources */, 127 | FA2263BA28D455E300FEE0CA /* glacier_float.cpp in Sources */, 128 | FA2263C028D4560500FEE0CA /* glacier_float.cpp in Sources */, 129 | ); 130 | runOnlyForDeploymentPostprocessing = 0; 131 | }; 132 | /* End PBXSourcesBuildPhase section */ 133 | 134 | /* Begin XCBuildConfiguration section */ 135 | FA2263AE28D4558E00FEE0CA /* Debug */ = { 136 | isa = XCBuildConfiguration; 137 | buildSettings = { 138 | ALWAYS_SEARCH_USER_PATHS = NO; 139 | CLANG_ANALYZER_NONNULL = YES; 140 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 141 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 142 | CLANG_ENABLE_MODULES = YES; 143 | CLANG_ENABLE_OBJC_ARC = YES; 144 | CLANG_ENABLE_OBJC_WEAK = YES; 145 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 146 | CLANG_WARN_BOOL_CONVERSION = YES; 147 | CLANG_WARN_COMMA = YES; 148 | CLANG_WARN_CONSTANT_CONVERSION = YES; 149 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 150 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 151 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 152 | CLANG_WARN_EMPTY_BODY = YES; 153 | CLANG_WARN_ENUM_CONVERSION = YES; 154 | CLANG_WARN_INFINITE_RECURSION = YES; 155 | CLANG_WARN_INT_CONVERSION = YES; 156 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 157 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 158 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 159 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 160 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 161 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 162 | CLANG_WARN_STRICT_PROTOTYPES = YES; 163 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 164 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 165 | CLANG_WARN_UNREACHABLE_CODE = YES; 166 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 167 | COPY_PHASE_STRIP = NO; 168 | DEBUG_INFORMATION_FORMAT = dwarf; 169 | ENABLE_STRICT_OBJC_MSGSEND = YES; 170 | ENABLE_TESTABILITY = YES; 171 | GCC_C_LANGUAGE_STANDARD = gnu11; 172 | GCC_DYNAMIC_NO_PIC = NO; 173 | GCC_NO_COMMON_BLOCKS = YES; 174 | GCC_OPTIMIZATION_LEVEL = 0; 175 | GCC_PREPROCESSOR_DEFINITIONS = ( 176 | "DEBUG=1", 177 | "$(inherited)", 178 | ); 179 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 180 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 181 | GCC_WARN_UNDECLARED_SELECTOR = YES; 182 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 183 | GCC_WARN_UNUSED_FUNCTION = YES; 184 | GCC_WARN_UNUSED_VARIABLE = YES; 185 | IPHONEOS_DEPLOYMENT_TARGET = 15.5; 186 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 187 | MTL_FAST_MATH = YES; 188 | ONLY_ACTIVE_ARCH = YES; 189 | SDKROOT = iphoneos; 190 | }; 191 | name = Debug; 192 | }; 193 | FA2263AF28D4558E00FEE0CA /* Release */ = { 194 | isa = XCBuildConfiguration; 195 | buildSettings = { 196 | ALWAYS_SEARCH_USER_PATHS = NO; 197 | CLANG_ANALYZER_NONNULL = YES; 198 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 199 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 200 | CLANG_ENABLE_MODULES = YES; 201 | CLANG_ENABLE_OBJC_ARC = YES; 202 | CLANG_ENABLE_OBJC_WEAK = YES; 203 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 204 | CLANG_WARN_BOOL_CONVERSION = YES; 205 | CLANG_WARN_COMMA = YES; 206 | CLANG_WARN_CONSTANT_CONVERSION = YES; 207 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 208 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 209 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 210 | CLANG_WARN_EMPTY_BODY = YES; 211 | CLANG_WARN_ENUM_CONVERSION = YES; 212 | CLANG_WARN_INFINITE_RECURSION = YES; 213 | CLANG_WARN_INT_CONVERSION = YES; 214 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 215 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 216 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 217 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 218 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 219 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 220 | CLANG_WARN_STRICT_PROTOTYPES = YES; 221 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 222 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 223 | CLANG_WARN_UNREACHABLE_CODE = YES; 224 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 225 | COPY_PHASE_STRIP = NO; 226 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 227 | ENABLE_NS_ASSERTIONS = NO; 228 | ENABLE_STRICT_OBJC_MSGSEND = YES; 229 | GCC_C_LANGUAGE_STANDARD = gnu11; 230 | GCC_NO_COMMON_BLOCKS = YES; 231 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 232 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 233 | GCC_WARN_UNDECLARED_SELECTOR = YES; 234 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 235 | GCC_WARN_UNUSED_FUNCTION = YES; 236 | GCC_WARN_UNUSED_VARIABLE = YES; 237 | IPHONEOS_DEPLOYMENT_TARGET = 15.5; 238 | MTL_ENABLE_DEBUG_INFO = NO; 239 | MTL_FAST_MATH = YES; 240 | SDKROOT = iphoneos; 241 | VALIDATE_PRODUCT = YES; 242 | }; 243 | name = Release; 244 | }; 245 | FA2263B128D4558E00FEE0CA /* Debug */ = { 246 | isa = XCBuildConfiguration; 247 | buildSettings = { 248 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 249 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 250 | CODE_SIGN_STYLE = Automatic; 251 | CURRENT_PROJECT_VERSION = 1; 252 | DEVELOPMENT_TEAM = 7425H6FX5M; 253 | GENERATE_INFOPLIST_FILE = YES; 254 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 255 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 256 | INFOPLIST_KEY_UIMainStoryboardFile = Main; 257 | INFOPLIST_KEY_UIRequiredDeviceCapabilities = metal; 258 | INFOPLIST_KEY_UIStatusBarHidden = YES; 259 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 260 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 261 | LD_RUNPATH_SEARCH_PATHS = ( 262 | "$(inherited)", 263 | "@executable_path/Frameworks", 264 | ); 265 | MARKETING_VERSION = 1.0; 266 | PRODUCT_BUNDLE_IDENTIFIER = "com.glacier.testgame.deterministic-float-ios"; 267 | PRODUCT_NAME = "$(TARGET_NAME)"; 268 | SWIFT_EMIT_LOC_STRINGS = YES; 269 | TARGETED_DEVICE_FAMILY = "1,2"; 270 | }; 271 | name = Debug; 272 | }; 273 | FA2263B228D4558E00FEE0CA /* Release */ = { 274 | isa = XCBuildConfiguration; 275 | buildSettings = { 276 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 277 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 278 | CODE_SIGN_STYLE = Automatic; 279 | CURRENT_PROJECT_VERSION = 1; 280 | DEVELOPMENT_TEAM = 7425H6FX5M; 281 | GENERATE_INFOPLIST_FILE = YES; 282 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 283 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 284 | INFOPLIST_KEY_UIMainStoryboardFile = Main; 285 | INFOPLIST_KEY_UIRequiredDeviceCapabilities = metal; 286 | INFOPLIST_KEY_UIStatusBarHidden = YES; 287 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 288 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 289 | LD_RUNPATH_SEARCH_PATHS = ( 290 | "$(inherited)", 291 | "@executable_path/Frameworks", 292 | ); 293 | MARKETING_VERSION = 1.0; 294 | PRODUCT_BUNDLE_IDENTIFIER = "com.glacier.testgame.deterministic-float-ios"; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_EMIT_LOC_STRINGS = YES; 297 | TARGETED_DEVICE_FAMILY = "1,2"; 298 | }; 299 | name = Release; 300 | }; 301 | /* End XCBuildConfiguration section */ 302 | 303 | /* Begin XCConfigurationList section */ 304 | FA22637A28D4558E00FEE0CA /* Build configuration list for PBXProject "deterministic_float_ios" */ = { 305 | isa = XCConfigurationList; 306 | buildConfigurations = ( 307 | FA2263AE28D4558E00FEE0CA /* Debug */, 308 | FA2263AF28D4558E00FEE0CA /* Release */, 309 | ); 310 | defaultConfigurationIsVisible = 0; 311 | defaultConfigurationName = Release; 312 | }; 313 | FA2263B028D4558E00FEE0CA /* Build configuration list for PBXNativeTarget "deterministic_float_ios" */ = { 314 | isa = XCConfigurationList; 315 | buildConfigurations = ( 316 | FA2263B128D4558E00FEE0CA /* Debug */, 317 | FA2263B228D4558E00FEE0CA /* Release */, 318 | ); 319 | defaultConfigurationIsVisible = 0; 320 | defaultConfigurationName = Release; 321 | }; 322 | /* End XCConfigurationList section */ 323 | }; 324 | rootObject = FA22637728D4558E00FEE0CA /* Project object */; 325 | } 326 | -------------------------------------------------------------------------------- /deterministic/glacier_float.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 zhou xuan, Email: zhouxuan6676@gmail.com 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at * 6 | * http://www.apache.org/licenses/LICENSE-2.0 * 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | #pragma once 14 | 15 | #include 16 | #include 17 | 18 | //#define GLACIER_MULTIPLY_NORAMLIZE_FAST 19 | 20 | #ifndef GLACIER_MULTIPLY_NORAMLIZE_FAST 21 | //#define GLACIER_NORMALIZE_TEST 22 | #endif 23 | 24 | #if defined( GLACIER_OVERFLOW_TEST) || defined( GLACIER_NORMALIZE_TEST) 25 | #include 26 | #include 27 | #endif 28 | 29 | 30 | #ifdef _MSC_VER 31 | #include 32 | #include 33 | #endif 34 | 35 | class GFloat // Get Glacier first char "G" for Name 36 | { 37 | public: 38 | static inline constexpr GFloat Zero() { return GFloat(0x000000, 0x00); }; 39 | static inline constexpr GFloat Half() { return GFloat(0x400000, 0x68); }; 40 | static inline constexpr GFloat One() { return GFloat(0x400000, 0x69); }; 41 | static inline constexpr GFloat Two() { return GFloat(0x400000, 0x6A); }; 42 | static inline constexpr GFloat Three() { return GFloat(0x600000, 0x6A); }; 43 | static inline constexpr GFloat Four() { return GFloat(0x400000, 0x6B); }; 44 | static inline constexpr GFloat Pi() { return GFloat(0x6487ef, 0x6a); };//Float(3,141592654, 1000000000); 45 | static inline constexpr GFloat Pi_Half() { return GFloat(0x6487ef, 0x69); }; 46 | static inline constexpr GFloat Pi_Quarter() { return GFloat(0x6487ef, 0x68); }; 47 | static inline constexpr GFloat Pi_Two() { return GFloat(0x6487ef, 0x6b); }; 48 | static inline constexpr GFloat Pi_Inv() { return GFloat(0x517cc1, 0x67); }; 49 | static inline constexpr GFloat Pi_TwoInv() { return GFloat(0x517cc1, 0x66); }; 50 | static inline constexpr GFloat e() { return GFloat(0x56fc2a, 0x6a); }; 51 | static inline constexpr GFloat e_Inv() { return GFloat(0x5e2d58, 0x67); }; 52 | static inline constexpr GFloat e_Div_2() { return GFloat(0x5c551d, 0x69); }; 53 | static inline constexpr GFloat Epsilon() { return GFloat(0x400000, 0x57); }; 54 | 55 | static inline constexpr GFloat Inv_10() { return GFloat(0x666666, 0x65); }; 56 | static inline constexpr GFloat Inv_100() { return GFloat(0x51eb85, 0x62); }; 57 | static inline constexpr GFloat Inv_1000() { return GFloat(0x418937, 0x5f); }; 58 | static inline constexpr GFloat Inv_10000() { return GFloat(0x68db8b, 0x5b); }; 59 | static inline constexpr GFloat Inv_100000() { return GFloat(0x53e2d6, 0x58); }; 60 | static inline constexpr GFloat Inv_1000000(){ return GFloat(0x431bde, 0x55); }; 61 | 62 | 63 | 64 | static inline uint32_t GBitScanReverse64( uint64_t num) 65 | { 66 | #ifdef _MSC_VER 67 | unsigned long Index; 68 | _BitScanReverse64(&Index, num); 69 | return Index; 70 | #elif __GNUC__ 71 | auto nCount = __builtin_clzll(num); 72 | return nCount == 64 ? 0 : 63 - nCount; 73 | #else 74 | for( int32_t nIndex = 63; nIndex >= 0; nIndex-- ) 75 | { 76 | if (((uint64_t)1 << nIndex) & num) 77 | { 78 | return nIndex; 79 | } 80 | } 81 | return 0; 82 | #endif 83 | } 84 | 85 | static inline uint32_t GBitScanReverse32(uint32_t num) 86 | { 87 | #ifdef _MSC_VER 88 | unsigned long Index; 89 | _BitScanReverse(&Index, num); 90 | return Index; 91 | #elif __GNUC__ 92 | auto nCount = __builtin_clz(num); 93 | return nCount == 32 ? 0 : 31 - nCount; 94 | #else 95 | for (int32_t nIndex = 31; nIndex >= 0; nIndex--) 96 | { 97 | if (((uint64_t)1 << nIndex) & num) 98 | { 99 | return nIndex; 100 | } 101 | } 102 | return 0; 103 | #endif 104 | } 105 | 106 | public: 107 | int32_t rawint32; 108 | 109 | public: 110 | 111 | static void Init(); 112 | 113 | constexpr GFloat(const GFloat&) = default; 114 | 115 | constexpr GFloat() : rawint32(0) 116 | { 117 | 118 | } 119 | 120 | explicit inline GFloat( int32_t TValue) 121 | { 122 | *this= Normalize32((int32_t)TValue, 127); 123 | } 124 | 125 | constexpr GFloat(int32_t Traw32, int32_t exp ) : 126 | rawint32((Traw32 << 8) | int32_t(exp & 0x000000FF)) 127 | { 128 | #if 0 129 | 130 | if( exp < 0 || exp > 0x000000FF ) 131 | { 132 | std::cout << __func__ << "( Traw32 : " << Traw32 <<" , exp : " << exp 133 | <<" ) , exp[0,255] exp has overflow!" < 0 && (Traw32 < 0x00400000 || Traw32 > 0x007FFFFF)) || 140 | (Traw32 < 0 && (Traw32 < (int32_t)0xFF800000 || Traw32 > (int32_t)0xFFC00000))) 141 | { 142 | std::cout << __func__ << "( Raw : " <> 8 ; 169 | } 170 | inline constexpr int32_t getfraction_NoShift() const 171 | { 172 | return int32_t(rawint32 & 0xFFFFFF00); 173 | } 174 | 175 | inline constexpr int32_t getfraction(int32_t shift) const 176 | { 177 | return getfraction() >> ( shift); 178 | } 179 | 180 | inline constexpr int32_t getexponent() const 181 | { 182 | return (rawint32 & 0xFF); 183 | } 184 | 185 | static inline constexpr GFloat FromRaw32(int32_t Traw32) 186 | { 187 | GFloat T; 188 | T.rawint32 = Traw32; 189 | return T; 190 | } 191 | 192 | static inline constexpr GFloat FromFractionAndExp(int32_t Traw32, int32_t exp) 193 | { 194 | if (exp < 0) 195 | { 196 | return GFloat::Zero(); 197 | } 198 | exp = exp > 255 ? 255 : exp; 199 | 200 | return GFloat(Traw32, exp); 201 | } 202 | 203 | static inline GFloat FromFloat(float f) 204 | { 205 | if (f == 0.f || f == -0.f) 206 | return Zero(); 207 | 208 | int32_t T754Rawint32 = *(int32_t*)&f; 209 | int32_t TRraction = (int32_t)(T754Rawint32 & 0x007FFFFF) + 0x00800000; 210 | int32_t exponent = ((T754Rawint32 & 0x7FFFFFFF) >> 23 ); 211 | 212 | if (T754Rawint32 < 0) 213 | TRraction = -TRraction; 214 | 215 | //return Normalize(TRraction >> 1,exponent - 22); 216 | return GFloat::FromFractionAndExp(TRraction >> 1,exponent - 22); 217 | } 218 | 219 | double toDouble() const 220 | { 221 | int32_t Texponent = getexponent() - 127; 222 | double dT = pow(2, Texponent); 223 | double dResult = getfraction() * dT; 224 | 225 | return (dResult); 226 | } 227 | 228 | float toFloat() const 229 | { 230 | return (float)toDouble(); 231 | } 232 | 233 | static inline GFloat Normalize32(int32_t Trawvalue, int32_t Texponent) 234 | { 235 | if (Trawvalue == 0) 236 | return GFloat(0, 0); 237 | 238 | int32_t index = GBitScanReverse32(abs(Trawvalue)); 239 | 240 | if (index <= 22) 241 | { 242 | int32_t uDelta = 22 - index; 243 | return GFloat::FromFractionAndExp(Trawvalue << uDelta, Texponent - uDelta); 244 | } 245 | else 246 | { 247 | int32_t uDelta = index - 22; 248 | return GFloat::FromFractionAndExp(Trawvalue >> uDelta, Texponent + uDelta); 249 | } 250 | } 251 | 252 | static inline GFloat Normalize64(int64_t Trawvalue, int32_t Texponent) 253 | { 254 | if( Trawvalue == 0 ) 255 | return GFloat(0,0); 256 | 257 | int32_t index = GBitScanReverse64(abs(Trawvalue )); 258 | 259 | if ( index <= 22 ) 260 | { 261 | int32_t uDelta = 22 - index; 262 | return GFloat::FromFractionAndExp((int32_t)(Trawvalue << uDelta), Texponent - uDelta); 263 | } 264 | else 265 | { 266 | int32_t uDelta = index - 22; 267 | return GFloat::FromFractionAndExp((int32_t)(Trawvalue >> uDelta), Texponent + uDelta); 268 | } 269 | } 270 | 271 | inline bool IsNormalize() const 272 | { 273 | int32_t absRaw = abs( getfraction()); 274 | 275 | if ( absRaw !=0 && ( absRaw < 0x00400000 || absRaw > 0x007FFFFF)) 276 | { 277 | return false; 278 | } 279 | else 280 | { 281 | return true; 282 | } 283 | } 284 | 285 | inline GFloat operator +( const GFloat b) const 286 | { 287 | int32_t a_Frac = getfraction_NoShift(); 288 | int32_t b_Frac = b.getfraction_NoShift(); 289 | int32_t a_e = getexponent(); 290 | int32_t b_e = b.getexponent(); 291 | 292 | if( a_Frac==0) 293 | return Normalize32(b.getfraction(), b.getexponent()); 294 | if (b_Frac == 0) 295 | return Normalize32(getfraction(), getexponent()); 296 | 297 | if (a_e >= b_e) 298 | { 299 | int32_t nShift = a_e - b_e > 23 ? 23 : a_e - b_e; 300 | return Normalize64((int64_t)a_Frac + ((int64_t)b_Frac >> nShift), a_e - 8); 301 | } 302 | else 303 | { 304 | int32_t nShift = b_e - a_e > 23 ? 23 : b_e - a_e; 305 | return Normalize64((int64_t)b_Frac + ((int64_t)a_Frac >> nShift), b_e - 8); 306 | } 307 | 308 | } 309 | 310 | inline const GFloat operator +=(const GFloat b) 311 | { 312 | *this = *this + b; 313 | return *this; 314 | } 315 | 316 | inline constexpr bool operator ==(const GFloat b) const 317 | { 318 | return rawint32 == b.rawint32; 319 | } 320 | 321 | inline constexpr bool operator !=( const GFloat b) const 322 | { 323 | return rawint32 != b.rawint32; 324 | } 325 | 326 | inline const GFloat operator -() const 327 | { 328 | int32_t nFraction = getfraction(); 329 | 330 | //return GFloat::FromFractionAndExp(-nFraction, getexponent()); 331 | return GFloat::Normalize32(-nFraction, getexponent()); 332 | } 333 | 334 | inline const GFloat operator -( const GFloat b) const 335 | { 336 | return *this + (-b); 337 | } 338 | 339 | inline const GFloat operator -=(GFloat b) 340 | { 341 | *this = *this - b; 342 | return *this; 343 | } 344 | 345 | 346 | #ifdef GLACIER_MULTIPLY_NORAMLIZE_FAST 347 | 348 | inline const GFloat operator *(const GFloat b) const 349 | { 350 | // I assume a and b is normalized, if a or b is zero,it will get a correct result 351 | int64_t Trawvalue = (int64_t)getfraction() * b.getfraction_NoShift(); 352 | int32_t Texponent = getexponent() + b.getexponent() - 103; 353 | 354 | return GFloat::FromFractionAndExp((int32_t)(Trawvalue >> 32), Texponent); 355 | } 356 | #else 357 | 358 | inline const GFloat operator *(GFloat b) const 359 | { 360 | int64_t Trawvalue = (int64_t)getfraction() * b.getfraction(); 361 | int32_t Texponent = getexponent() + b.getexponent() - 127; 362 | return GFloat::Normalize64(Trawvalue, Texponent); 363 | } 364 | #endif 365 | inline const GFloat operator *=(GFloat b) 366 | { 367 | *this = *this * b; 368 | return *this; 369 | } 370 | 371 | inline const GFloat operator /(const GFloat b) const 372 | { 373 | int32_t nDivid = (int32_t)b.getfraction(); 374 | if (nDivid == 0) // for stable 375 | { 376 | return GFloat(0); 377 | } 378 | 379 | int64_t Trawvalue = ((int64_t)getfraction() << 32) / nDivid; 380 | int32_t Texponent = getexponent() - b.getexponent() + 127 - 32; 381 | 382 | return GFloat::Normalize64(Trawvalue, Texponent); 383 | } 384 | 385 | inline const GFloat operator /=(GFloat b) 386 | { 387 | *this = *this / b; 388 | return *this; 389 | } 390 | 391 | inline bool operator > (const GFloat b) const 392 | { 393 | int32_t a_fra = getfraction_NoShift(); 394 | int32_t b_fra = b.getfraction_NoShift(); 395 | 396 | if( a_fra == 0 || b_fra == 0) 397 | return a_fra > b_fra; 398 | 399 | int32_t a_e = getexponent();// -127; 400 | int32_t b_e = b.getexponent();//-127; 401 | 402 | if (a_e >= b_e) 403 | { 404 | int32_t nShift = a_e - b_e; 405 | return (int64_t)a_fra > ((int64_t)b_fra >> (nShift > 31 ? 31 : nShift)); 406 | } 407 | else 408 | { 409 | int32_t nShift = b_e - a_e; 410 | return ((int64_t)a_fra >> (nShift > 31 ? 31 : nShift)) > (int64_t)b_fra; 411 | } 412 | } 413 | 414 | inline bool operator >= (const GFloat b) const 415 | { 416 | return (rawint32 == b.rawint32) || (*this > b); 417 | } 418 | 419 | inline bool operator < (const GFloat b) const 420 | { 421 | return !(*this >= b); 422 | } 423 | 424 | inline bool operator <= (const GFloat b) const 425 | { 426 | return !(*this > b); 427 | } 428 | 429 | inline int32_t GetWhole() const 430 | { 431 | int32_t exp = (getexponent() - 127); 432 | if (exp >= 0) 433 | { 434 | return getfraction() << exp;// exp > 8 will overflow 435 | } 436 | else if (exp > -23) 437 | { 438 | int32_t Frac = getfraction(); 439 | if( rawint32 >= 0) 440 | { 441 | return Frac >> -exp; 442 | } 443 | else 444 | { 445 | return -((-Frac) >> -exp); 446 | } 447 | } 448 | else 449 | { 450 | return 0; 451 | } 452 | } 453 | 454 | inline int32_t GetWhole(GFloat& OutFraction) const 455 | { 456 | int32_t exp = (getexponent() - 127); 457 | if (exp >= 0) 458 | { 459 | OutFraction = Zero(); 460 | return getfraction() << exp; // exp > 8 will overflow 461 | } 462 | else if (exp > -23) 463 | { 464 | int32_t fra = getfraction(); 465 | int32_t fraMask = (1 << -exp) - 1; 466 | 467 | if( fra >= 0 ) 468 | { 469 | int32_t TRaw = fra >> -exp; 470 | int32_t TRra = fra & fraMask; 471 | OutFraction = GFloat::Normalize32(TRra << (23 + exp), 127 - 23); 472 | return TRaw; 473 | } 474 | else 475 | { 476 | int32_t TRaw = -fra >> -exp; 477 | int32_t TRra = -fra & fraMask; 478 | OutFraction = GFloat::Normalize32( -TRra << (23 + exp), 127 - 23); 479 | return -TRaw; 480 | } 481 | } 482 | else 483 | { 484 | OutFraction = *this; 485 | return 0; 486 | } 487 | } 488 | 489 | static inline GFloat Ceil( const GFloat value) 490 | { 491 | int32_t exp = (value.getexponent() - 127); 492 | 493 | if (exp >= 0) 494 | return value; 495 | else if (exp > -23)// 22 or 23 496 | { 497 | GFloat TFloor = GFloat::FromFractionAndExp((value.getfraction() >> -exp) << -exp, exp + 127); 498 | return TFloor == value ? TFloor : TFloor + One(); 499 | } 500 | else 501 | { 502 | return value.getfraction() > 0 ? One() : Zero(); 503 | } 504 | 505 | } 506 | static inline GFloat Floor(const GFloat value) 507 | { 508 | int32_t exp = (value.getexponent() - 127); 509 | 510 | if (exp >= 0) 511 | return value; 512 | else if( exp > -23 ) 513 | { 514 | return GFloat::FromFractionAndExp((value.getfraction() >> -exp) << -exp, exp + 127); 515 | } 516 | else 517 | { 518 | return value.getfraction() > 0 ? Zero() : -One(); 519 | } 520 | } 521 | 522 | static inline int32_t FloorToInt( const GFloat value) 523 | { 524 | int32_t exp = (value.getexponent() - 127); 525 | int32_t fra = value.getfraction(); 526 | if (exp >= 0) 527 | { 528 | return fra << exp;// exp > 8 will overflow 529 | } 530 | else if (exp > -23) 531 | { 532 | return fra >> -exp; 533 | } 534 | else 535 | { 536 | if (fra >= 0) 537 | return 0; 538 | else 539 | return -1; 540 | } 541 | } 542 | 543 | static inline int32_t CeilToInt(const GFloat value) 544 | { 545 | int32_t exp = (value.getexponent() - 127); 546 | int32_t fra = value.getfraction(); 547 | if (exp >= 0) 548 | { 549 | return fra << exp;// exp > 8 will overflow 550 | } 551 | else if (exp > -23) 552 | { 553 | int32_t fraMask = (1 << -exp) - 1; 554 | 555 | if( fraMask & fra ) 556 | { 557 | return (fra >> -exp ) + 1; 558 | } 559 | else 560 | { 561 | return (fra >> -exp ); 562 | } 563 | } 564 | else 565 | { 566 | if (fra >= 0) 567 | return 1; 568 | else 569 | return 0; 570 | } 571 | } 572 | 573 | static inline GFloat Abs(const GFloat value) 574 | { 575 | return value.rawint32 >= 0 ? value : -value; 576 | } 577 | 578 | static GFloat Sin(const GFloat value); 579 | static GFloat Cos(const GFloat value); 580 | static void SinCos(const GFloat value, GFloat& OutSin, GFloat& OutCos); 581 | static GFloat ASin(const GFloat value); 582 | static GFloat ACos(const GFloat value); 583 | static GFloat Tan(const GFloat value); 584 | static GFloat ATan(const GFloat value); 585 | static GFloat ATan2(const GFloat y, const GFloat x); 586 | static GFloat Exp(const GFloat value){return Pow2(value * e_Div_2());} 587 | static GFloat Log(const GFloat value); 588 | static GFloat Log2(const GFloat value); 589 | static GFloat Log10(const GFloat value); 590 | static GFloat Pow2(const GFloat value); 591 | static GFloat Pow(const GFloat base, const GFloat exponent) { if (base.rawint32 <= 0) return Zero(); return Pow2(exponent * Log2(base)); } 592 | static GFloat InvSqrt(const GFloat value ); 593 | static GFloat Sqrt(const GFloat value){return value * InvSqrt(value);} 594 | static GFloat Fmod(const GFloat x, const GFloat y){ GFloat t = x / y; GFloat out = Zero(); int32_t n = t.GetWhole(out); return x - GFloat(n) * y;} 595 | public: 596 | static constexpr int32_t ms_TriTableBit = 8; 597 | static constexpr int32_t ms_TriCount = 1 << ms_TriTableBit; 598 | 599 | private: 600 | 601 | static int32_t ms_SinCosTable[ms_TriCount*2]; 602 | }; 603 | 604 | -------------------------------------------------------------------------------- /deterministic/deterministic_float.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 zhou xuan, Email: zhouxuan6676@gmail.com 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at * 6 | * http://www.apache.org/licenses/LICENSE-2.0 * 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | #include "deterministic_float.h" 14 | #include "glacier_float.h" 15 | #include "glacier_platform.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #if UseProfiler_RDTSCP 24 | 25 | static double CountCpuGhz() { 26 | 27 | Myclock::time_point tStart = Myclock::now();; 28 | uint64_t uStart = GTimer::get_CPUCycles(); 29 | 30 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); 31 | 32 | uint64_t uEnd = GTimer::get_CPUCycles(); 33 | Myclock::time_point tEnd = Myclock::now(); 34 | 35 | double time = double(std::chrono::duration_cast(tEnd - tStart).count() * 1e-9); 36 | 37 | double CpuGhz = double(uEnd - uStart) / (time * 1000000000); 38 | return CpuGhz; 39 | 40 | } 41 | 42 | double GTimer::InvCPUGHZ = 0.000001f / CountCpuGhz(); 43 | #endif 44 | 45 | 46 | class GFloatTest 47 | { 48 | public: 49 | std::vector fa; 50 | std::vector fb; 51 | std::vector fc; 52 | std::vector da; 53 | std::vector db; 54 | std::vector dc; 55 | std::vector Ga; 56 | std::vector Gb; 57 | std::vector Gc; 58 | 59 | int N; 60 | double time1 = 0; 61 | double time2 = 0; 62 | GTimer Timer; 63 | std::ofstream m_string; 64 | 65 | GFloatTest(int TN) 66 | { 67 | GFloat::Init(); 68 | N = TN; 69 | fa.resize(N); 70 | fb.resize(N); 71 | fc.resize(N); 72 | da.resize(N); 73 | db.resize(N); 74 | dc.resize(N); 75 | Ga.resize(N); 76 | Gb.resize(N); 77 | Gc.resize(N); 78 | 79 | std::string FileName; 80 | #ifdef _WIN64 81 | FileName = "../../Test_BenchMark_Win"; 82 | if( GetCpuName().find( "12900H" ) != std::string::npos ) 83 | { 84 | FileName += "_12900H.md"; 85 | } 86 | else if( GetCpuName().find( "5950X" ) != std::string::npos ) 87 | { 88 | FileName += "_5950X.md"; 89 | } 90 | else 91 | { 92 | FileName = "_None.md"; 93 | } 94 | 95 | m_string = std::ofstream (FileName); 96 | #elif __OSX__ 97 | FileName = "../Test_BenchMark_OSX.md"; 98 | #endif 99 | 100 | std::stringstream Tstring; 101 | 102 | std::time_t TNow = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); 103 | 104 | #ifdef _MSC_VER 105 | char str[26]; 106 | ctime_s(str, sizeof str, &TNow); 107 | #else 108 | char* str = ctime(&TNow); 109 | #endif 110 | Tstring << "# GFloat Test And BenchMark" << std::endl; 111 | Tstring << " * Test time : "<< str << std::endl; 112 | 113 | 114 | Tstring << "|Operation System| C++ Compiler version |CPU | Base Frequency |" < dis(RMin, RMax); 140 | for (int i = 0; i < N; i++) { 141 | fa[i] = (float)dis(gen); 142 | fb[i] = (float)dis(gen); 143 | fc[i] = 1.f; 144 | 145 | Ga[i] = GFloat::FromFloat(fa[i]); 146 | Gb[i] = GFloat::FromFloat(fb[i]); 147 | Gc[i] = GFloat(0); 148 | } 149 | for (int i = 0; i < N; i++) { 150 | fc[i] = 1.f / sqrtf(fa[i]); 151 | Gc[i] = GFloat::InvSqrt(Ga[i]); 152 | } 153 | 154 | float fMaxAbs = 100000000.f; 155 | GFloat BestStart = GFloat::Zero(); 156 | for (GFloat GStart = GFloat(0, 8, 10); GStart < GFloat(0, 9, 10); GStart += GFloat(0, 1, 1000)) 157 | { 158 | float fabs = 0; 159 | for (int i = 0; i < N; i++) 160 | { 161 | fc[i] = 1.f / sqrtf(fa[i]); 162 | Gc[i] = GFloat::InvSqrt(Ga[i]/*,GStart*/); 163 | 164 | if (Gc[i] != GFloat::Zero()) 165 | { 166 | fabs += abs(Gc[i].toFloat() - fc[i]); 167 | } 168 | } 169 | std::cout << "Current fabs " << fabs << std::endl; 170 | if (fMaxAbs > fabs) 171 | { 172 | BestStart = GStart; 173 | fMaxAbs = fabs; 174 | } 175 | } 176 | 177 | std::cout << "fMaxAbs " << fMaxAbs << std::endl; 178 | std::cout << "Best GStart " << BestStart.rawint32 << " " << BestStart.toFloat() << std::endl; 179 | return BestStart.rawint32; 180 | } 181 | 182 | enum EGType 183 | { 184 | ERelative = 1, 185 | EAbsolute = 2, 186 | EOrignal = 4, 187 | EAll = 7 188 | }; 189 | 190 | inline void FunError( int NCount, EGType TType, std::string name, double RMin, double RMax, 191 | std::function fun_f, 192 | std::function fun_G) 193 | { 194 | std::string CurrentType; 195 | 196 | if( TType == EGType::ERelative ) 197 | CurrentType = "Relative"; 198 | else if( TType == EGType::EAbsolute) 199 | CurrentType = "Absolute"; 200 | else 201 | CurrentType = "Graph"; 202 | 203 | std::ofstream fs("../GFloat_" + name + "_" + CurrentType + ".gp"); 204 | 205 | fs << "set term svg size 640, 480" << std::endl; 206 | fs << "set output \"GFloat_" + name + "_" + CurrentType + ".svg\"" << std::endl; 207 | fs << R"gp(set format y "%g%%")gp" << std::endl; 208 | fs << "set title \"GFloat::" + name + "() " + CurrentType + " Error\"" << std::endl; 209 | fs << "unset key" << std::endl; 210 | fs << "plot \"-\" with points" << std::endl; 211 | 212 | fs << std::setprecision(std::numeric_limits::digits10 + 1); 213 | 214 | double delta = abs( RMax - RMin ) / NCount; 215 | double TMin = fmin( RMin, RMax ); 216 | double TMax = fmax( RMin, RMax); 217 | 218 | for (double i = TMin; i < TMax; i += delta) { 219 | double fy = fun_f(i); 220 | double Gy = fun_G(i); 221 | 222 | double ferror = 0; 223 | 224 | if (TType == EGType::ERelative) 225 | { 226 | if( abs(fy) > 0.0000001 ) 227 | ferror = (Gy - fy) * 100.0 / abs(fy); 228 | } 229 | else if (TType == EGType::EAbsolute) 230 | ferror = (Gy - fy) * 100.0; 231 | else 232 | ferror = (Gy ) * 100.0; 233 | 234 | fs << i << " " << ferror << std::endl; 235 | } 236 | 237 | fs << "EOF" << std::endl; 238 | } 239 | 240 | inline void FunGraph(std::string name, int NCount, EGType TType, float RMin, float RMax, 241 | std::function fun_f, 242 | std::function fun_G) 243 | { 244 | if (TType & EGType::ERelative) 245 | { 246 | FunError(NCount, EGType::ERelative, name, RMin, RMax, fun_f, fun_G ); 247 | } 248 | if (TType & EGType::EAbsolute) 249 | { 250 | FunError(NCount, EGType::EAbsolute, name, RMin, RMax, fun_f, fun_G); 251 | } 252 | if (TType & EGType::EOrignal) 253 | { 254 | FunError(NCount, EGType::EOrignal, name, RMin, RMax, fun_f, fun_G); 255 | } 256 | } 257 | 258 | inline void FunTest( 259 | std::string name, 260 | double RMin, double RMax, 261 | std::function fun_f, 262 | std::function fun_d, 263 | std::function fun_G ) 264 | { 265 | std::minstd_rand gen; 266 | std::uniform_real_distribution<> dis(RMin, RMax); 267 | 268 | int32_t nScaleTime = 5; 269 | int32_t Niner = N / nScaleTime; 270 | 271 | for( int nLog = 0; nLog < nScaleTime; nLog++ ) 272 | { 273 | double dt = 1. / pow(10,nLog); 274 | 275 | for (int j = 0; j < Niner; j++) 276 | { 277 | int i = nLog * Niner + j; 278 | double fda = dis(gen) * dt; 279 | double fdb = dis(gen) * dt; 280 | 281 | Ga[i] = GFloat::FromFloat((float)fda); 282 | Gb[i] = GFloat::FromFloat((float)fdb); 283 | fa[i] = Ga[i].toFloat(); 284 | fb[i] = Gb[i].toFloat(); 285 | da[i] = Ga[i].toDouble(); 286 | db[i] = Gb[i].toDouble(); 287 | 288 | fc[i] = 2.5f; 289 | dc[i] = 2.5f; 290 | Gc[i] = GFloat(2, 1, 2); 291 | 292 | } 293 | } 294 | 295 | Timer.Start(); 296 | { 297 | fun_f(N); 298 | } 299 | time1 = Timer.GetDeltaTimeMS(); 300 | 301 | fun_d(N); 302 | 303 | Timer.Start(); 304 | { 305 | fun_G(N); 306 | } 307 | time2 = Timer.GetDeltaTimeMS(); 308 | 309 | Count(RMin, RMax,name ); 310 | } 311 | 312 | void Count(double RMin, double RMax, std::string Name ) 313 | { 314 | double f1 = 0; 315 | double f2 = 0; 316 | 317 | double Maxabs = 0; 318 | double RMaxabs = 0; 319 | int maxi = 0; 320 | 321 | int nCount = 0; 322 | double totalabs = 0; 323 | 324 | for (int i = 0; i < N; i++) 325 | { 326 | double cf1 = (fc[i]); 327 | double cf2 = (Gc[i].toDouble()); 328 | 329 | // double cf2 = (fc[i]); 330 | if( abs(cf1) < 0.0000000000001 ) 331 | continue; 332 | double cAbs = abs((cf2 - cf1) / cf1 ); 333 | totalabs += cAbs; 334 | nCount++; 335 | if (Maxabs < cAbs) 336 | { 337 | Maxabs = cAbs; 338 | maxi = i; 339 | } 340 | 341 | if( RMaxabs < abs(cf2 - cf1)) 342 | { 343 | RMaxabs = abs(cf2 - cf1); 344 | } 345 | 346 | f1 += abs(cf1); 347 | f2 += abs(cf2); 348 | } 349 | 350 | double avgerror = totalabs / nCount; 351 | 352 | std::stringstream Tstring; 353 | std::cout.precision(3); 354 | 355 | double timeratio = time1 / time2; 356 | 357 | 358 | Tstring << "|" << std::setiosflags(std::ios::left) << std::setw(12) << Name; 359 | Tstring << "|[" << std::setiosflags(std::ios::right) << std::setw(9) << std::setiosflags(std::ios::fixed)< 1 ) 367 | Tstring << "**" << timeratio << "** |"<< std::endl; 368 | else 369 | Tstring << timeratio << " |"<< std::endl; 370 | 371 | GPrintLog( Tstring ); 372 | 373 | if( m_string.is_open() ) 374 | m_string << Tstring.str(); 375 | } 376 | }; 377 | // why add 3, for Resist the c++ compiler optimizations 378 | 379 | #define GMYFun( a, c ) \ 380 | {\ 381 | for (int j = 0; j < N/3; j++ )\ 382 | {\ 383 | int i = j*3;GFloat f; \ 384 | (c) = (a);i++;\ 385 | (c) = (a);i++;\ 386 | (c) = (a);\ 387 | }\ 388 | }\ 389 | 390 | void TestGFloat::Run() 391 | { 392 | // std::cout << std::hex << GFloat(3,0,2).rawint32 << std::endl; 393 | 394 | GFloatTest FT(1000000); 395 | 396 | bool bErrortest =0; 397 | if (bErrortest) 398 | { 399 | float fstart = 20.f; 400 | FT.FunGraph("Sin", 1000, GFloatTest::EGType::EAll, -fstart, fstart, [&](double i)->double {return (double)sinf( (float)i); }, [&](double i)->double {return GFloat::Sin(GFloat::FromFloat((float)i)).toDouble(); }); 401 | FT.FunGraph("ASin", 1000, GFloatTest::EGType::EAll, -1, 1, [&](double i)->double {return (double)asinf((float)i); }, [&](double i)->double {return GFloat::ASin(GFloat::FromFloat((float)i)).toDouble(); }); 402 | FT.FunGraph("ACos", 1000, GFloatTest::EGType::EAll, -1, 1, [&](double i)->double {return (double)acosf((float)i); }, [&](double i)->double {return GFloat::ACos(GFloat::FromFloat((float)i)).toDouble(); }); 403 | FT.FunGraph("Exp", 1000, GFloatTest::EGType::EAll, -fstart, fstart, [&](double i)->double {return (double)expf((float)i); }, [&](double i)->double {return GFloat::Exp(GFloat::FromFloat((float)i)).toDouble(); }); 404 | FT.FunGraph("Pow2", 1000, GFloatTest::EGType::EAll, -fstart, fstart, [&](double i)->double {return (double)powf(2.f,(float)i); }, [&](double i)->double {return GFloat::Pow2(GFloat::FromFloat((float)i)).toDouble(); }); 405 | FT.FunGraph("Log", 1000, GFloatTest::EGType::EAll, 0, 100000.f, [&](double i)->double {return (double)logf( (float)i); }, [&](double i)->double {return GFloat::Log(GFloat::FromFloat((float)i)).toDouble(); }); 406 | return; 407 | } 408 | 409 | FT.FunTest("Mul+Add", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i] * FT.fb[i] + FT.fb[i], FT.fc[i])}, [&](int N)->void {GMYFun(FT.da[i] * FT.db[i] + FT.db[i], FT.dc[i])}, [&](int N)->void {GMYFun(FT.Ga[i] * FT.Gb[i] + FT.Gb[i], FT.Gc[i]) }); 410 | 411 | FT.FunTest("Add", -10000.f, 10000.f, [&](int N)->void{GMYFun(FT.fa[i] + FT.fb[i], FT.fc[i])}, [&](int N)->void{GMYFun(FT.da[i] + FT.db[i], FT.dc[i])}, [&](int N)->void {GMYFun(FT.Ga[i] + FT.Gb[i], FT.Gc[i])}); 412 | FT.FunTest("Sub", -10000.f, 10000.f, [&](int N)->void{GMYFun(FT.fa[i] - FT.fb[i], FT.fc[i])}, [&](int N)->void{GMYFun(FT.da[i] - FT.db[i], FT.dc[i])}, [&](int N)->void {GMYFun(FT.Ga[i] - FT.Gb[i], FT.Gc[i] ) }); 413 | FT.FunTest("Mul", -10000.f, 10000.f, [&](int N)->void{GMYFun(FT.fa[i] * FT.fb[i], FT.fc[i])}, [&](int N)->void{GMYFun(FT.da[i] * FT.db[i], FT.dc[i])}, [&](int N)->void {GMYFun(FT.Ga[i] * FT.Gb[i], FT.Gc[i] ) }); 414 | FT.FunTest("Div", -10000.f, 10000.f, [&](int N)->void{GMYFun(FT.fa[i] / FT.fb[i], FT.fc[i])}, [&](int N)->void{GMYFun(FT.da[i] / FT.db[i], FT.dc[i])}, [&](int N)->void {GMYFun(FT.Ga[i] / FT.Gb[i], FT.Gc[i] ) }); 415 | FT.FunTest("Ceil", -10000.f, 10000.f, [&](int N)->void{GMYFun(ceilf(FT.fa[i]) , FT.fc[i])}, [&](int N)->void{GMYFun(ceil(FT.da[i]), FT.dc[i] )}, [&](int N)->void {GMYFun(GFloat::Ceil(FT.Ga[i]), FT.Gc[i])}); 416 | FT.FunTest("Floor", -10000.f, 10000.f, [&](int N)->void{GMYFun(floorf(FT.fa[i]) , FT.fc[i])}, [&](int N)->void{GMYFun(floor(FT.da[i]), FT.dc[i])}, [&](int N)->void {GMYFun(GFloat::Floor(FT.Ga[i]), FT.Gc[i])}); 417 | FT.FunTest("Whole", -10000.f, 10000.f, [&](int N)->void{GMYFun((float)int(FT.fa[i]),FT.fc[i])}, [&](int N)->void{GMYFun((double)int(FT.da[i]), FT.dc[i])}, [&](int N)->void {GMYFun(GFloat(FT.Ga[i].GetWhole()), FT.Gc[i] )}); 418 | FT.FunTest("WholeFrac", -10000.f, 10000.f, [&](int N)->void{GMYFun((float)FT.fa[i] , FT.fc[i])}, [&](int N)->void{GMYFun((double)FT.da[i], FT.dc[i])}, [&](int N)->void {GMYFun(GFloat(FT.Ga[i].GetWhole(f)) + f, FT.Gc[i])}); 419 | FT.FunTest("Fraction", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i] - (float)FT.fa[i], FT.fc[i])}, [&](int N)->void {GMYFun(FT.da[i] - (double)FT.da[i], FT.dc[i])}, [&](int N)->void {GMYFun((FT.Ga[i].GetWhole(f), f), FT.Gc[i])}); 420 | 421 | FT.FunTest("-()", -10000.f, 10000.f, [&](int N)->void{GMYFun(-FT.fa[i], FT.fc[i])}, [&](int N)->void{GMYFun(-FT.da[i], FT.dc[i]) }, [&](int N)->void {GMYFun(-FT.Ga[i], FT.Gc[i]) }); 422 | FT.FunTest(">()", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i] > FT.fb[i] ? FT.fa[i] : FT.fb[i], FT.fc[i])}, [&](int N)->void {GMYFun(FT.da[i] > FT.db[i] ? FT.da[i] : FT.db[i], FT.dc[i])}, [&](int N)->void { GMYFun(FT.Ga[i] > FT.Gb[i] ? FT.Ga[i] : FT.Gb[i], FT.Gc[i]) }); 423 | FT.FunTest("<()", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i] < FT.fb[i] ? FT.fa[i] : FT.fb[i], FT.fc[i])}, [&](int N)->void {GMYFun(FT.da[i] < FT.db[i] ? FT.da[i] : FT.db[i], FT.dc[i])}, [&](int N)->void { GMYFun(FT.Ga[i] < FT.Gb[i] ? FT.Ga[i] : FT.Gb[i], FT.Gc[i]) }); 424 | FT.FunTest(">=()", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i] >= FT.fb[i] ? FT.fa[i] : FT.fb[i], FT.fc[i])}, [&](int N)->void {GMYFun(FT.da[i] >= FT.db[i] ? FT.da[i] : FT.db[i], FT.dc[i])}, [&](int N)->void { GMYFun(FT.Ga[i] >= FT.Gb[i] ? FT.Ga[i] : FT.Gb[i], FT.Gc[i]) }); 425 | FT.FunTest("<=()", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i] <= FT.fb[i] ? FT.fa[i] : FT.fb[i], FT.fc[i])}, [&](int N)->void {GMYFun(FT.da[i] <= FT.db[i] ? FT.da[i] : FT.db[i], FT.dc[i])}, [&](int N)->void { GMYFun(FT.Ga[i] <= FT.Gb[i] ? FT.Ga[i] : FT.Gb[i], FT.Gc[i]) }); 426 | 427 | FT.FunTest("Abs", -10000.f, 10000.f, [&](int N)->void {GMYFun(abs(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(abs(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Abs(FT.Ga[i]), FT.Gc[i]) }); 428 | FT.FunTest("Normalize32", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i], FT.fc[i] )}, [&](int N)->void {GMYFun(FT.da[i], FT.dc[i])}, [&](int N)->void {GMYFun(GFloat::Normalize32(FT.Ga[i].getfraction(), FT.Ga[i].getexponent()), FT.Gc[i])}); 429 | FT.FunTest("Normalize64", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i], FT.fc[i])}, [&](int N)->void {GMYFun(FT.da[i], FT.dc[i])}, [&](int N)->void {GMYFun(GFloat::Normalize64((int64_t)FT.Ga[i].getfraction(), FT.Ga[i].getexponent()), FT.Gc[i])}); 430 | FT.FunTest("FromInt", -10000.f, 10000.f, [&](int N)->void {GMYFun((float)int(FT.fa[i]),FT.fc[i])},[&](int N)->void {GMYFun((double)int(FT.da[i]),FT.dc[i])}, [&](int N)->void {GMYFun(GFloat((int)FT.fa[i]), FT.Gc[i]) }); 431 | FT.FunTest("Fromfloat", -10000.f, 10000.f, [&](int N)->void {GMYFun(FT.fa[i], FT.fc[i])}, [&](int N)->void {GMYFun(FT.da[i], FT.dc[i])}, [&](int N)->void {GMYFun(FT.Ga[i], FT.Gc[i]) }); 432 | FT.FunTest("CeilToInt", -10000.f, 10000.f, [&](int N)->void {GMYFun(ceilf(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(ceil(FT.da[i]), FT.dc[i])}, [&](int N)->void {GMYFun(GFloat( GFloat::CeilToInt( FT.Ga[i])), FT.Gc[i]) }); 433 | FT.FunTest("FloorToInt", -10000.f, 10000.f, [&](int N)->void {GMYFun(floorf(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(floor(FT.da[i]), FT.dc[i])}, [&](int N)->void {GMYFun(GFloat( GFloat::FloorToInt(FT.Ga[i])), FT.Gc[i]) }); 434 | 435 | 436 | // return; 437 | FT.FunTest("Sin", -10000.f, 10000.f, [&](int N)->void {GMYFun(sinf(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(sin(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Sin(FT.Ga[i]), FT.Gc[i])}); 438 | FT.FunTest("Cos", -10000.f, 10000.f, [&](int N)->void {GMYFun(cosf(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(cos(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Cos(FT.Ga[i]), FT.Gc[i])}); 439 | FT.FunTest("Tan", -10000.f, 10000.f, [&](int N)->void {GMYFun(tanf(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(tan(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Tan(FT.Ga[i]), FT.Gc[i])}); 440 | FT.FunTest("ASin", -1.f, 1.f, [&](int N)->void {GMYFun(asinf(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(asin(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::ASin(FT.Ga[i]), FT.Gc[i])}); 441 | FT.FunTest("ACos", -1.f, 1.f, [&](int N)->void {GMYFun(acosf(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(acos(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::ACos(FT.Ga[i]), FT.Gc[i])}); 442 | FT.FunTest("ATan", -10000.f, 10000.f, [&](int N)->void {GMYFun(atanf(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(atan(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::ATan(FT.Ga[i]), FT.Gc[i])}); 443 | FT.FunTest("ATan(10,x)", -10000.f, 10000.f, [&](int N)->void {GMYFun(atan2f(10.f,FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(atan2(10.,FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::ATan2(GFloat(10),FT.Ga[i]), FT.Gc[i])}); 444 | FT.FunTest("ATan(x,10)", -10000.f, 10000.f, [&](int N)->void {GMYFun(atan2f(FT.fa[i],10.f), FT.fc[i])}, [&](int N)->void {GMYFun(atan2(FT.da[i],10.), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::ATan2(FT.Ga[i],GFloat(10)), FT.Gc[i])}); 445 | // return; 446 | FT.FunTest("Sqrt", 0.f, 10000.f, [&](int N)->void{GMYFun(sqrtf(FT.fa[i]), FT.fc[i])}, [&](int N)->void{GMYFun(sqrt(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Sqrt(FT.Ga[i]), FT.Gc[i])}); 447 | FT.FunTest("InvSqrt", 0.f, 10000.f, [&](int N)->void{GMYFun(1.f/sqrtf(FT.fa[i]), FT.fc[i])},[&](int N)->void{GMYFun(1./sqrt(FT.da[i]),FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::InvSqrt(FT.Ga[i]), FT.Gc[i])}); 448 | FT.FunTest("Exp", -20.f, 20.f, [&](int N)->void{GMYFun(expf(FT.fa[i]), FT.fc[i])}, [&](int N)->void{GMYFun(exp(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Exp(FT.Ga[i]), FT.Gc[i])}); 449 | FT.FunTest("Pow2", -30.f, 30.f, [&](int N)->void{GMYFun(powf(2.f, FT.fa[i]), FT.fc[i])},[&](int N)->void {GMYFun(pow(2., FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Pow2(FT.Ga[i]), FT.Gc[i])}); 450 | FT.FunTest("Log_e", 0.f, 10000.f, [&](int N)->void{GMYFun(logf(FT.fa[i]), FT.fc[i])}, [&](int N)->void{GMYFun(log(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Log(FT.Ga[i]), FT.Gc[i])}); 451 | FT.FunTest("Log_2", 0.f, 10000.f, [&](int N)->void{GMYFun(log2f(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(log2(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Log2(FT.Ga[i]), FT.Gc[i])}); 452 | FT.FunTest("Log_10", 0.f, 10000.f, [&](int N)->void {GMYFun(log10f(FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(log10(FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Log10(FT.Ga[i]), FT.Gc[i])}); 453 | 454 | FT.FunTest("Pow(1.7,x)", -30.f, 30.f, [&](int N)->void{GMYFun(powf(1.7f, FT.fa[i]), FT.fc[i])},[&](int N)->void{GMYFun(pow(1.7, FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Pow(GFloat(1,7,10), FT.Ga[i]), FT.Gc[i])}); 455 | FT.FunTest("Pow(x,1.7)", 0.55f, 20, [&](int N)->void{GMYFun(powf(FT.fa[i], 1.7f), FT.fc[i])},[&](int N)->void{GMYFun(pow(FT.da[i], 1.7), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Pow(FT.Ga[i], GFloat(1,7,10)), FT.Gc[i])}); 456 | FT.FunTest("Fmod(x,1.7)", -10000.f, 10000.f, [&](int N)->void {GMYFun(fmodf(FT.fa[i], 1.7f), FT.fc[i])}, [&](int N)->void {GMYFun(fmod(FT.da[i], 1.7), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Fmod(FT.Ga[i], GFloat(1, 7, 10)), FT.Gc[i])}); 457 | FT.FunTest("Fmod(1.7,x)", -10000.f, 10000.f, [&](int N)->void {GMYFun(fmodf(1.7f,FT.fa[i]), FT.fc[i])}, [&](int N)->void {GMYFun(fmodf(1.7,FT.da[i]), FT.dc[i])}, [&](int N)->void { GMYFun(GFloat::Fmod(GFloat(1, 7, 10), FT.Ga[i] ), FT.Gc[i])}); 458 | 459 | } 460 | 461 | 462 | -------------------------------------------------------------------------------- /deterministic/glacier_float.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 zhou xuan, Email: zhouxuan6676@gmail.com 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at * 6 | * http://www.apache.org/licenses/LICENSE-2.0 * 7 | * Unless required by applicable law or agreed to in writing, software 8 | * distributed under the License is distributed on an "AS IS" BASIS, 9 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | * See the License for the specific language governing permissions and 11 | * limitations under the License. 12 | */ 13 | 14 | #include "glacier_float.h" 15 | 16 | #include 17 | 18 | 19 | template 20 | class GFixedType32 21 | { 22 | public: 23 | 24 | explicit inline constexpr GFixedType32(int32_t raw) 25 | : rawInt32(raw) 26 | { 27 | 28 | } 29 | // construct number like 2.46, GFixedType32(2,46/100), -23.678 -GFixedType32(23,678/1000) 30 | explicit inline constexpr GFixedType32(uint32_t a, uint64_t b, uint64_t c) : 31 | rawInt32(int32_t(((int64_t)a << FractionNumType) | ((((uint64_t)b) << FractionNumType) / c))) 32 | { 33 | 34 | } 35 | 36 | static inline constexpr int32_t GetTypeNumber() 37 | { 38 | return FractionNumType; 39 | } 40 | 41 | inline constexpr GFixedType32 operator +(GFixedType32 b) const 42 | { 43 | return GFixedType32(rawInt32 + b.rawInt32); 44 | } 45 | inline constexpr GFixedType32 operator +=(GFixedType32 b) 46 | { 47 | *this = *this + b; 48 | return *this; 49 | } 50 | 51 | inline constexpr GFixedType32 operator -() const 52 | { 53 | return GFixedType32(-rawInt32); 54 | } 55 | 56 | inline constexpr GFixedType32 operator -(GFixedType32 b) const 57 | { 58 | return GFixedType32(rawInt32 - b.rawInt32); 59 | } 60 | 61 | inline constexpr GFixedType32 operator *(GFixedType32 b) const 62 | { 63 | return GFixedType32(((int64_t)rawInt32 * (int64_t)b.rawInt32) >> FractionNumType); 64 | } 65 | 66 | inline constexpr GFixedType32 operator /(GFixedType32 b) const 67 | { 68 | return GFixedType32(((((int64_t)rawInt32)<::GetTypeNumber(); 74 | 75 | if (exp >= 0) 76 | { 77 | return GFixedType32(Value.getfraction() << exp); 78 | } 79 | else 80 | { 81 | return GFixedType32(Value.getfraction() >> -exp); 82 | } 83 | } 84 | 85 | inline constexpr GFloat ToGFloat() const 86 | { 87 | return GFloat::Normalize32(rawInt32, 127 - GFixedType32::GetTypeNumber()); 88 | } 89 | 90 | int32_t rawInt32; 91 | }; 92 | 93 | typedef GFixedType32<8> GFixed08; 94 | typedef GFixedType32<16> GFixed16; 95 | typedef GFixedType32<26> GFixed26; 96 | typedef GFixedType32<27> GFixed27; //-16~16 97 | typedef GFixedType32<28> GFixed28; //-8~8 98 | typedef GFixedType32<29> GFixed29; //-4~4 99 | typedef GFixedType32<30> GFixed30; //-2~2 100 | typedef GFixedType32<31> GFixed31; //-1~1 101 | 102 | 103 | int32_t GFloat::ms_SinCosTable[GFloat::ms_TriCount * 2] = { 104 | 0, 1073741824, 26350944, 1073418368, 52686016, 1072448384, 78989344, 1070832384, 105 | 105245104, 1068571392, 131437456, 1065666816, 157550624, 1062120192, 183568928, 1057933824, 106 | 209476640, 1053110144, 235258144, 1047652096, 260897984, 1041563136, 286380672, 1034846592, 107 | 311690752, 1027506816, 336813184, 1019548032, 361732736, 1010975232, 386434368, 1001793408, 108 | 410903232, 992008064, 435124544, 981625216, 459083776, 970651136, 482766464, 959092224, 109 | 506158400, 946955648, 529245440, 934248704, 552013568, 920979072, 574449280, 907154560, 110 | 596539008, 892783616, 618269312, 877874944, 639627264, 862437504, 660599936, 846480512, 111 | 681174656, 830013568, 701339008, 813046784, 721080960, 795590144, 740388480, 777654400, 112 | 759250048, 759250048, 777654400, 740388480, 795590272, 721080832, 813046784, 701338880, 113 | 830013568, 681174528, 846480512, 660599808, 862437504, 639627264, 877874944, 618269312, 114 | 892783744, 596538880, 907154560, 574449280, 920979072, 552013568, 934248704, 529245376, 115 | 946955776, 506158272, 959092224, 482766464, 970651136, 459083776, 981625216, 435124480, 116 | 992008064, 410903168, 1001793408, 386434240, 1010975232, 361732672, 1019548160, 336813120, 117 | 1027506816, 311690752, 1034846592, 286380608, 1041563136, 260897920, 1047652096, 235258144, 118 | 1053110144, 209476544, 1057933824, 183568896, 1062120192, 157550656, 1065666816, 131437408, 119 | 1068571392, 105245088, 1070832384, 78989264, 1072448384, 52685984, 1073418368, 26350844, 120 | 1073741824, -47, 1073418368, -26350940, 1072448384, -52686088, 1070832384, -78989360, 121 | 1068571392, -105245200, 1065666688, -131437504, 1062120192, -157550752, 1057933824, -183568992, 122 | 1053110144, -209476640, 1047652096, -235258240, 1041563136, -260898016, 1034846592, -286380736, 123 | 1027506816, -311690880, 1019548032, -336813184, 1010975232, -361732800, 1001793408, -386434368, 124 | 992008064, -410903296, 981625216, -435124608, 970651136, -459083776, 959092224, -482766528, 125 | 946955648, -506158528, 934248832, -529245376, 920979072, -552013696, 907154560, -574449408, 126 | 892783616, -596539136, 877874944, -618269312, 862437504, -639627392, 846480384, -660600064, 127 | 830013696, -681174656, 813046784, -701339008, 795590144, -721081088, 777654272, -740388736, 128 | 759250048, -759250176, 740388480, -777654528, 721080832, -795590400, 701339008, -813046784, 129 | 681174528, -830013696, 660599808, -846480640, 639627008, -862437632, 618269312, -877875072, 130 | 596538880, -892783744, 574449152, -907154688, 552013568, -920979072, 529245312, -934248832, 131 | 506158272, -946955904, 482766528, -959092352, 459083712, -970651136, 435124416, -981625344, 132 | 410903040, -992008192, 386434368, -1001793408, 361732672, -1010975360, 336813056, -1019548160, 133 | 311690816, -1027506944, 286380608, -1034846720, 260897856, -1041563136, 235257984, -1047652224, 134 | 209476608, -1053110272, 183568832, -1057933824, 157550496, -1062120192, 131437488, -1065666816, 135 | 105245056, -1068571520, 78989216, -1070832512, 52685808, -1072448512, 26350924, -1073418496, 136 | -94, -1073741824, -26351112, -1073418496, -52686000, -1072448512, -78989408, -1070832512, 137 | -105245248, -1068571520, -131437680, -1065666816, -157550688, -1062120192, -183569056, -1057933824, 138 | -209476832, -1053110144, -235258176, -1047652224, -260898048, -1041563136, -286380800, -1034846720, 139 | -311691008, -1027506816, -336813248, -1019548160, -361732864, -1010975232, -386434560, -1001793408, 140 | -410903232, -992008064, -435124672, -981625216, -459083968, -970651136, -482766720, -959092224, 141 | -506158464, -946955776, -529245504, -934248704, -552013824, -920979072, -574449408, -907154688, 142 | -596539136, -892783616, -618269568, -877874944, -639627264, -862437504, -660599936, -846480512, 143 | -681174784, -830013568, -701339136, -813046656, -721080960, -795590272, -740388608, -777654400, 144 | -759250304, -759250048, -777654400, -740388608, -795590272, -721080960, -813046784, -701339136, 145 | -830013696, -681174656, -846480640, -660599936, -862437632, -639627136, -877875200, -618269184, 146 | -892783872, -596538752, -907154816, -574449024, -920979072, -552013696, -934248832, -529245440, 147 | -946955776, -506158336, -959092352, -482766400, -970651264, -459083648, -981625344, -435124288, 148 | -992008320, -410902912, -1001793408, -386434432, -1010975232, -361732736, -1019548160, -336813184, 149 | -1027506944, -311690688, -1034846720, -286380480, -1041563264, -260897696, -1047652352, -235257824, 150 | -1053110144, -209476704, -1057933824, -183568928, -1062120192, -157550592, -1065666816, -131437312, 151 | -1068571520, -105244880, -1070832512, -78989056, -1072448512, -52685640, -1073418496, -26351008, 152 | -1073741824, 12, -1073418496, 26351028, -1072448512, 52686176, -1070832512, 78989584, 153 | -1068571520, 105245408, -1065666816, 131437840, -1062120192, 157550592, -1057933824, 183568960, 154 | -1053110144, 209476736, -1047652224, 235258336, -1041563136, 260898208, -1034846592, 286380928, 155 | -1027506816, 311691136, -1019548160, 336813120, -1010975232, 361732736, -1001793408, 386434432, 156 | -992008064, 410903360, -981625216, 435124800, -970651008, 459084096, -959092096, 482766848, 157 | -946955776, 506158336, -934248832, 529245440, -920979072, 552013696, -907154560, 574449408, 158 | -892783616, 596539136, -877874816, 618269568, -862437632, 639627136, -846480512, 660599808, 159 | -830013696, 681174656, -813046784, 701339008, -795590144, 721081088, -777654272, 740388736, 160 | -759249920, 759250304, -740388608, 777654272, -721080960, 795590144, -701339008, 813046784, 161 | -681174528, 830013696, -660599808, 846480640, -639627008, 862437632, -618269056, 877875200, 162 | -596539136, 892783616, -574449408, 907154560, -552013568, 920979072, -529245312, 934248832, 163 | -506158208, 946955776, -482766208, 959092352, -459083456, 970651264, -435124608, 981625216, 164 | -410903232, 992008064, -386434304, 1001793408, -361732608, 1010975232, -336812992, 1019548160, 165 | -311690496, 1027506944, -286380288, 1034846720, -260898048, 1041563136, -235258144, 1047652096, 166 | -209476544, 1053110144, -183568768, 1057933824, -157550400, 1062120192, -131437136, 1065666816, 167 | -105244704, 1068571520, -78989392, 1070832384, -52685976, 1072448384, -26350832, 1073418368 168 | }; 169 | 170 | 171 | void GFloat::Init() 172 | { 173 | for( int32_t i = 0; i = exp || exp >= 64) 201 | { 202 | Delta = GFixed30(0,0,1); 203 | return 0; 204 | } 205 | 206 | int64_t InvPi = 87496355274; // I spend 2 hours to find so good number 207 | 208 | int64_t TRaw = value.getfraction() * (int64_t)InvPi; 209 | 210 | int64_t NewRaw = exp >= 0 ? TRaw << exp : TRaw >> -exp; 211 | 212 | GFixed30 F30Fraction = GFixed30((NewRaw>>9) & 0x3FFFFFFF); 213 | 214 | int32_t TWhole = F30Fraction.rawInt32 >> (30 - GFloat::ms_TriTableBit); 215 | 216 | constexpr GFixed30 C_quaterPi(0, 785398164, 1000000000); 217 | 218 | GFixed30 delta_1 = GFixed30(F30Fraction.rawInt32 & ((1 << (30 - GFloat::ms_TriTableBit)) - 1)); 219 | 220 | Delta = C_quaterPi * delta_1; 221 | 222 | Delta.rawInt32 = Delta.rawInt32 << 3; 223 | 224 | int32_t nWhole = (TWhole) & (GFloat::ms_TriCount - 1); 225 | 226 | return nWhole; 227 | } 228 | 229 | static inline GFixed30 s_TriClamp(int32_t exp, const GFloat value) 230 | { 231 | int64_t Inv_TwoPi = 87496355274; // 39 bits, I spend 2 hours to find so good number 232 | 233 | int64_t TRaw = value.getfraction() * (int64_t)Inv_TwoPi; 234 | 235 | int64_t NewRaw = exp >= 0 ? TRaw << exp : TRaw >> -exp; 236 | 237 | GFixed30 F30Fraction = GFixed30((NewRaw >> 9) & 0x3FFFFFFF); 238 | 239 | return F30Fraction; 240 | } 241 | 242 | static inline GFixed29 s_NormalToRadus( const GFixed30 value ) 243 | { 244 | int64_t Pi_Two = 6746518852; // 30 bits fraction 245 | 246 | return GFixed29( int32_t( (value.rawInt32 * Pi_Two) >> 31)); 247 | } 248 | 249 | GFloat GFloat::Sin(const GFloat value) 250 | { 251 | #if 1 252 | int32_t exp = value.getexponent() - 127; 253 | 254 | if (-64 >= exp || exp >= 64) 255 | { 256 | return Zero(); 257 | } 258 | 259 | GFixed30 F30Fraction = s_TriClamp( exp, value);// 260 | 261 | GFixed30 TValue(0); 262 | 263 | if(F30Fraction.rawInt32 >= GFixed30(0,3,4).rawInt32) 264 | { 265 | TValue = F30Fraction - GFixed30(1, 0, 4); 266 | } 267 | else if( F30Fraction.rawInt32 >= GFixed30(0,1,4).rawInt32) 268 | { 269 | TValue = GFixed30(0,1,2) - F30Fraction; 270 | } 271 | else 272 | { 273 | TValue = F30Fraction; 274 | } 275 | 276 | GFixed29 x1 = s_NormalToRadus( TValue); 277 | 278 | GFixed29 x2 = x1 * x1; 279 | 280 | GFixed29 TResult = 281 | x1 * ( GFixed29(0, 999999, 1000000) + 282 | x2 * (-GFixed29(0, 166656, 1000000) + 283 | x2 * ( GFixed29(0, 8312, 1000000) - 284 | x2 * GFixed29(0, 185, 1000000)))); 285 | 286 | return TResult.ToGFloat(); 287 | 288 | #else 289 | 290 | GFixed30 F30Delte(0); 291 | 292 | int32_t nWhole = Sin_Table(value, F30Delte ); 293 | 294 | GFixed30 TableSin = GFixed30(ms_SinCosTable[nWhole * 2]); 295 | GFixed30 TableCos = GFixed30(ms_SinCosTable[nWhole * 2 + 1]); 296 | 297 | GFixed30 FixedResult = TableSin + F30Delte * ( TableCos - TableSin * GFixed30(F30Delte.rawInt32 >> 1)); 298 | 299 | return FixedResult.ToGFloat(); 300 | 301 | #endif 302 | } 303 | 304 | GFloat GFloat::Cos(const GFloat value) 305 | { 306 | #if 1 307 | int32_t exp = value.getexponent() - 127; 308 | 309 | if (-64 >= exp || exp >= 64) 310 | { 311 | return One(); 312 | } 313 | 314 | GFixed30 F30Fraction = s_TriClamp(exp, value); 315 | 316 | GFixed30 TValue(0); 317 | 318 | bool bNegative = false; 319 | 320 | if (F30Fraction.rawInt32 >= GFixed30(0, 3, 4).rawInt32) 321 | { 322 | TValue = F30Fraction - GFixed30(1, 0, 4); 323 | } 324 | else if(F30Fraction.rawInt32 >= GFixed30(0, 1, 4).rawInt32) 325 | { 326 | TValue = F30Fraction - GFixed30(0, 2, 4); 327 | bNegative = true; 328 | } 329 | else 330 | { 331 | TValue = F30Fraction; 332 | } 333 | 334 | GFixed29 x1 = s_NormalToRadus(TValue); 335 | 336 | GFixed29 x2 = x1 * x1; 337 | 338 | GFixed29 TResult = GFixed29(0, 999972, 1000000) + 339 | x2 * (-GFixed29(0, 499792, 1000000) + 340 | x2 * ( GFixed29(0, 413742, 10000000) - 341 | x2 * GFixed29(0, 124311, 100000000))); 342 | 343 | if(bNegative) 344 | TResult = -TResult; 345 | 346 | return TResult.ToGFloat(); 347 | #else 348 | 349 | GFixed30 F30Delte(0); 350 | 351 | int32_t nWhole = Sin_Table(value, F30Delte); 352 | 353 | GFixed30 TableSin = GFixed30(ms_SinCosTable[nWhole * 2]); 354 | GFixed30 TableCos = GFixed30(ms_SinCosTable[nWhole * 2 + 1]); 355 | 356 | GFixed30 FixedResult = TableCos - F30Delte * (TableSin + TableCos * GFixed30(F30Delte.rawInt32 >> 1)); 357 | return FixedResult.ToGFloat(); 358 | 359 | #endif 360 | } 361 | void GFloat::SinCos(const GFloat value, GFloat& OutSin, GFloat& OutCos) 362 | { 363 | #if 1 364 | OutSin = Sin(value); 365 | OutCos = Cos(value); 366 | 367 | #else 368 | 369 | GFixed30 F30Delte(0); 370 | 371 | int32_t nWhole = Sin_Table(value, F30Delte); 372 | GFixed30 TableSin = GFixed30(ms_SinCosTable[nWhole * 2]); 373 | GFixed30 TableCos = GFixed30(ms_SinCosTable[nWhole * 2 + 1]); 374 | 375 | OutSin = (TableSin + F30Delte * ( TableCos - TableSin * GFixed30(F30Delte.rawInt32 >> 1))).ToGFloat(); 376 | OutCos = (TableCos - F30Delte * ( TableSin + TableCos * GFixed30(F30Delte.rawInt32 >> 1))).ToGFloat(); 377 | 378 | #endif 379 | } 380 | GFloat GFloat::ASin(const GFloat value) 381 | { 382 | constexpr GFloat TOne = GFloat::FromRaw32( One().rawint32 ); 383 | if( value > TOne) 384 | { 385 | return Pi_Half(); 386 | } 387 | else if (value <-TOne ) 388 | { 389 | return -Pi_Half(); 390 | } 391 | else 392 | { 393 | GFixed30 x1 = GFixed30::FromGFloat(value); 394 | 395 | GFixed30 GFStart(0,98,100); 396 | 397 | if( -GFStart.rawInt32 < x1.rawInt32 && x1.rawInt32 < GFStart.rawInt32 ) 398 | { 399 | GFixed30 x2 = x1 * x1; 400 | 401 | auto TResult = 402 | x1 * (GFixed30(1, 0, 2) + 403 | x2 * (GFixed30(0, 1, 6) + 404 | x2 * (GFixed30(0, 3, 40) + 405 | x2 * (GFixed30(0, 5, 112) + 406 | x2 * (GFixed30(0, 35, 1152) + 407 | x2 * (GFixed30(0, 63, 2816) + 408 | x2 * (GFixed30(0, 231, 13312) + 409 | x2 * (GFixed30(0, 143, 10240) + 410 | x2 * (GFixed30(0, 6435, 557056) + 411 | x2 * (GFixed30(0, 12155, 1245184) )))))))))); 412 | 413 | return TResult.ToGFloat() ; 414 | } 415 | else 416 | { 417 | GFixed30 FPi_Half(1,570796327,1000000000); 418 | GFixed30 ASin_098(1, 37046148,100000000); 419 | 420 | if(x1.rawInt32 > 0 ) 421 | { 422 | GFixed30 FDelta = x1 - GFStart; 423 | 424 | auto TResult = ASin_098 + (FPi_Half - ASin_098) * FDelta / (GFixed30(1, 0, 2) - GFStart); 425 | 426 | return TResult.ToGFloat(); 427 | } 428 | else 429 | { 430 | GFixed30 FDelta = -x1 - GFStart; 431 | 432 | auto TResult = ASin_098 + (FPi_Half - ASin_098) * FDelta / (GFixed30(1, 0, 2) - GFStart); 433 | 434 | return (-TResult).ToGFloat(); 435 | } 436 | } 437 | } 438 | } 439 | GFloat GFloat::ACos(const GFloat value) 440 | { 441 | return Pi_Half()- ASin(value); 442 | } 443 | GFloat GFloat::Tan(const GFloat value) 444 | { 445 | GFloat TSin; 446 | GFloat TCos; 447 | SinCos(value, TSin, TCos); 448 | return TSin / TCos; 449 | } 450 | 451 | static inline GFloat s_ATan( const GFloat value ) 452 | { 453 | GFixed30 x1 = GFixed30::FromGFloat(value); 454 | GFixed30 x2 = x1 * x1; 455 | GFixed30 TResult = 456 | x1 * ( GFixed30(0,999788,1000000) + 457 | x2 * (-GFixed30(0,325808,1000000) + 458 | x2 * ( GFixed30(0,155579,1000000) - 459 | x2 * GFixed30(0,443266,10000000))) ); 460 | 461 | return TResult.ToGFloat(); 462 | } 463 | 464 | GFloat GFloat::ATan(const GFloat value) 465 | { 466 | if( -One() <= value && value <= One() ) 467 | { 468 | return s_ATan( value); 469 | } 470 | else 471 | { 472 | GFloat InvValue = One() / value; 473 | if (value > One()) 474 | { 475 | return Pi_Half() - s_ATan(InvValue ); 476 | } 477 | else 478 | { 479 | return -s_ATan(InvValue ) - Pi_Half(); 480 | } 481 | } 482 | } 483 | 484 | GFloat GFloat::ATan2(const GFloat y, const GFloat x) 485 | { 486 | if( x > Zero() ) 487 | { 488 | GFloat value = y / x; 489 | return ATan(value); 490 | } 491 | else if( x < Zero() ) 492 | { 493 | if( y > Zero() ) 494 | { 495 | return Pi() + ATan(y / x); 496 | } 497 | else 498 | { 499 | return ATan(y / x) - Pi(); 500 | } 501 | } 502 | else 503 | { 504 | if( y >= Zero() ) 505 | { 506 | return Pi_Half(); 507 | } 508 | else 509 | { 510 | return -Pi_Half(); 511 | } 512 | } 513 | } 514 | 515 | //MiniMaxApproximation[Log2[x], {x, {0.5, 0.999999}, 5, 0}] 516 | static inline int64_t s_Log2( const GFloat value) 517 | { 518 | int32_t TExp = value.getexponent() - 127 + 23; 519 | 520 | GFixed27 x1 = GFixed27(value.getfraction_NoShift()>>4); 521 | 522 | GFixed27 TResult = -GFixed27(3,72096,100000) + 523 | x1*( GFixed27(9, 62979, 100000) + 524 | x1*(-GFixed27(12, 68320, 100000) + 525 | x1*( GFixed27(10, 99420, 100000) + 526 | x1*(-GFixed27(5, 29593, 100000) + 527 | x1*( GFixed27(1, 7610, 100000)))))); 528 | 529 | int64_t TRaw = ( (int64_t)TExp << 32 ) + ( (int64_t)TResult.rawInt32 << (32 - GFixed27::GetTypeNumber() ) ); 530 | 531 | return TRaw; 532 | } 533 | 534 | GFloat GFloat::Log(const GFloat value) 535 | { 536 | if (value.rawint32 > 0) 537 | { 538 | GFixed26 Ln_2 = GFixed26(0, 69314718, 100000000); 539 | int64_t TRaw = (s_Log2(value) * Ln_2.rawInt32) >> GFixed26::GetTypeNumber(); 540 | return GFloat::Normalize64(TRaw, 127 - 32); 541 | } 542 | else 543 | { 544 | return Zero(); 545 | } 546 | } 547 | 548 | GFloat GFloat::Log2(const GFloat value) 549 | { 550 | if (value.rawint32 > 0 ) 551 | { 552 | int64_t TRaw = s_Log2(value); 553 | return GFloat::Normalize64(TRaw, 127 - 32); 554 | } 555 | else 556 | { 557 | return Zero(); 558 | } 559 | } 560 | 561 | GFloat GFloat::Log10(const GFloat value) 562 | { 563 | if (value.rawint32 > 0) 564 | { 565 | GFixed26 Ln_10 = GFixed26(0, 30103, 100000); 566 | int64_t TRaw = (s_Log2(value) * Ln_10.rawInt32) >> GFixed26::GetTypeNumber(); 567 | return GFloat::Normalize64(TRaw, 127 - 32); 568 | } 569 | else 570 | { 571 | return Zero(); 572 | } 573 | } 574 | 575 | GFloat GFloat::Pow2(const GFloat value) 576 | { 577 | GFloat fraction; 578 | int32_t nWhole = value.GetWhole(fraction); 579 | GFixed30 x1 = GFixed30::FromGFloat(fraction); 580 | GFixed30 FraExp = GFixed30(1,0,2) + 581 | x1 * ( GFixed30(0, 693149, 1000000) + 582 | x1 * ( GFixed30(0, 240218, 1000000) + 583 | x1 * ( GFixed30(0, 555287, 10000000) + 584 | x1 * ( GFixed30(0, 957624, 100000000) + 585 | x1 * ( GFixed30(0, 137819, 100000000) + 586 | x1 * ( GFixed30(0, 124773, 10000000000) + 587 | x1 * ( GFixed30(0, 2563, 1000000000)))))))); 588 | 589 | return GFloat::Normalize32( FraExp.rawInt32, 127 -30 + nWhole); 590 | } 591 | /* 592 | template 593 | class GFixedType64 594 | { 595 | public: 596 | 597 | explicit inline constexpr GFixedType64(int64_t raw) 598 | : rawInt64(raw) 599 | { 600 | 601 | } 602 | 603 | explicit inline constexpr GFixedType64(uint32_t a, uint32_t b, uint32_t c) : 604 | rawInt64(int64_t((a << FractionNumType) | ((((uint64_t)b) << FractionNumType) / c))) 605 | { 606 | 607 | } 608 | 609 | static inline constexpr int64_t GetTypeNumber() 610 | { 611 | return FractionNumType; 612 | } 613 | 614 | inline constexpr GFixedType64 operator +(GFixedType64 b) const 615 | { 616 | return GFixedType64(rawInt64 + b.rawInt64); 617 | } 618 | inline constexpr GFixedType64 operator +=(GFixedType64 b) 619 | { 620 | *this = *this + b; 621 | return *this; 622 | } 623 | 624 | inline constexpr GFixedType64 operator -() const 625 | { 626 | return GFixedType64(-rawInt64); 627 | } 628 | 629 | inline constexpr GFixedType64 operator -(GFixedType64 b) const 630 | { 631 | return GFixedType64(rawInt64 - b.rawInt64); 632 | } 633 | 634 | inline constexpr GFixedType64 operator *(GFixedType64 b) const 635 | { 636 | return GFixedType64(((int64_t)rawInt64 * (int64_t)b.rawInt64) >> FractionNumType); 637 | } 638 | 639 | static inline constexpr GFixedType64 FromGFloat(const GFloat Value) 640 | { 641 | int32_t exp = Value.getexponent() - 127 + GFixedType64::GetTypeNumber(); 642 | 643 | if (exp >= 0) 644 | { 645 | return GFixedType64( ((int64_t)Value.getfraction()) << exp); 646 | } 647 | else 648 | { 649 | return GFixedType64(( (int64_t)Value.getfraction() )>> -exp); 650 | } 651 | } 652 | 653 | inline constexpr GFloat ToGFloat() const 654 | { 655 | return GFloat::Normalize((int64_t)rawInt64, 127 - GFixedType64::GetTypeNumber()); 656 | } 657 | 658 | int64_t rawInt64; 659 | };*/ 660 | 661 | GFloat GFloat::InvSqrt(const GFloat fvalue ) 662 | { 663 | if (fvalue.rawint32 <= 0) 664 | return Zero(); 665 | 666 | GFloat value = GFloat::Normalize32( fvalue.getfraction(), fvalue.getexponent()); 667 | 668 | GFixed30 Fixed30(value.getfraction_NoShift() ); 669 | int32_t exp = value.getexponent() - 127 + 22; 670 | GFixed29 Start2(0); 671 | 672 | if(exp & 0x1) 673 | { 674 | Fixed30.rawInt32 >>= 1; 675 | exp += 1; 676 | GFixed29 X1 = GFixed29(Fixed30.rawInt32>>1); 677 | Start2 = GFixed29(2,60531,100000) + 678 | X1 *(-GFixed29(3, 63965,100000) + 679 | X1 *( GFixed29(2, 99053,100000) + 680 | X1 *(-GFixed29(0,956673,1000000)))); 681 | } 682 | else 683 | { 684 | GFixed29 X1 = GFixed29(Fixed30.rawInt32>>1); 685 | Start2 = GFixed29(1,84223,100000) + 686 | X1 *(-GFixed29(1, 28681,100000) + 687 | X1 *( GFixed29(0,528656,1000000) + 688 | X1 *(-GFixed29(0,84558,1000000)))); 689 | } 690 | 691 | Fixed30.rawInt32 >>= 1; 692 | 693 | GFixed30 Start = GFixed30( Start2.rawInt32 << 1); 694 | 695 | constexpr GFixed30 F1_5(1, 1, 2); 696 | 697 | Start = Start * (F1_5 - (Fixed30 * Start) * Start); // Newton's method 698 | 699 | GFloat TResult = GFloat::Normalize32(Start.rawInt32, 127 - GFixed30::GetTypeNumber() - (exp >> 1)); 700 | 701 | return TResult; 702 | } 703 | 704 | 705 | 706 | 707 | --------------------------------------------------------------------------------