Add integer square root to SCMP.
This commit is contained in:
		
							parent
							
								
									94672bba98
								
							
						
					
					
						commit
						f99d5a8356
					
				| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
cmake_minimum_required(VERSION 3.22)
 | 
					cmake_minimum_required(VERSION 3.22)
 | 
				
			||||||
project(scsl LANGUAGES CXX
 | 
					project(scsl LANGUAGES CXX
 | 
				
			||||||
        VERSION 1.1.3
 | 
					        VERSION 1.1.4
 | 
				
			||||||
        DESCRIPTION "Shimmering Clarity Standard Library")
 | 
					        DESCRIPTION "Shimmering Clarity Standard Library")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(CMAKE_CXX_STANDARD 14)
 | 
					set(CMAKE_CXX_STANDARD 14)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,6 +115,13 @@ WithinTolerance(T a, T b, T epsilon)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// \brief Integer square-root.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// \param n A max-value integer whose square root should be returned.
 | 
				
			||||||
 | 
					/// \return The square root of $n$.
 | 
				
			||||||
 | 
					size_t	ISqrt(size_t n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace scmp
 | 
					} // namespace scmp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,5 +151,37 @@ DefaultEpsilon(int& epsilon)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					ISqrt(size_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (n < 2) {
 | 
				
			||||||
 | 
							return n;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t	start = 0;
 | 
				
			||||||
 | 
						size_t	end = n / 2;
 | 
				
			||||||
 | 
						size_t	result = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (start <= end) {
 | 
				
			||||||
 | 
							auto middle = (start + end) >> 1;
 | 
				
			||||||
 | 
							result = middle * middle;
 | 
				
			||||||
 | 
							if (result == n) {
 | 
				
			||||||
 | 
								return middle;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (result < n) {
 | 
				
			||||||
 | 
								start = middle + 1;
 | 
				
			||||||
 | 
								result = middle;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								end = middle - 1;
 | 
				
			||||||
 | 
								result = middle;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace scmp
 | 
					} // namespace scmp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										30
									
								
								test/math.cc
								
								
								
								
							
							
						
						
									
										30
									
								
								test/math.cc
								
								
								
								
							| 
						 | 
					@ -116,6 +116,35 @@ RotateRadians()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool
 | 
				
			||||||
 | 
					IntegerSquareRoot()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static std::vector<size_t> ns{
 | 
				
			||||||
 | 
						    // standard integer roots
 | 
				
			||||||
 | 
						    4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    // a few float cases
 | 
				
			||||||
 | 
						    42, 90, 92
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						static std::vector<size_t> expected{
 | 
				
			||||||
 | 
						    // standard integer roots
 | 
				
			||||||
 | 
						    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    // a few float cases
 | 
				
			||||||
 | 
						    6, 9, 10
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SCTEST_CHECK_EQ(ns.size(), expected.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < ns.size(); i++) {
 | 
				
			||||||
 | 
							auto root = scmp::ISqrt(ns.at(i));
 | 
				
			||||||
 | 
							SCTEST_CHECK_EQ(root, expected.at(i));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // anonymous namespace
 | 
					} // anonymous namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,6 +177,7 @@ main(int argc, char *argv[])
 | 
				
			||||||
	suite.AddTest("WithinToleranceFloat", WithinToleranceFloat);
 | 
						suite.AddTest("WithinToleranceFloat", WithinToleranceFloat);
 | 
				
			||||||
	suite.AddTest("WithinToleranceDouble", WithinToleranceDouble);
 | 
						suite.AddTest("WithinToleranceDouble", WithinToleranceDouble);
 | 
				
			||||||
	suite.AddTest("RotateRadians", RotateRadians);
 | 
						suite.AddTest("RotateRadians", RotateRadians);
 | 
				
			||||||
 | 
						suite.AddTest("IntegerSquareRoot", IntegerSquareRoot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	delete flags;
 | 
						delete flags;
 | 
				
			||||||
	auto result = suite.Run();
 | 
						auto result = suite.Run();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue