Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Round with precision/decimal place #266

Open
thareh opened this issue Mar 10, 2023 · 2 comments
Open

[FR] Round with precision/decimal place #266

thareh opened this issue Mar 10, 2023 · 2 comments

Comments

@thareh
Copy link
Contributor

thareh commented Mar 10, 2023

Good day,

I'd be nice to be able to round floats/doubles to a certain decimal place and also convert floats/doubles to a "nice" looking string.

I've come up with a solution but surely there is a better way, and I don't know if my solution works on other platforms.

#include <sstream>
#include <iomanip>
#include <blitz.h>

extern "C" {
	BBString * bmx_double_to_string(double val, int precision){
		std::ostringstream str;
		str << std::fixed;
		str << std::setprecision(precision);
		str << val;
		
		return bbStringFromCString(str.str().c_str());
	}
}

Thanks!

@GWRon
Copy link
Contributor

GWRon commented Mar 10, 2023

This is my Blitzmax-based solution:

	'convert a double to a string
	'double is rounded to the requested amount of digits after comma
	Function NumberToString:String(number:Double, digitsAfterDecimalPoint:Int = 2, truncateZeros:Int = False)
		Local pow:Int = 10
		For Local i:Int = 1 Until digitsAfterDecimalPoint
			pow :* 10
		Next
		'slower than the loop!
		'local pow:int = int(10 ^ digitsAfterDecimalPoint)

		'bring all decimals in front of the dot, add 0.5 to "round"
		'divide "back" the rounded value
		Local tmp:Double = (number * pow + Sgn(number) * 0.5) / pow

		'find dot - and keep "digitsAfterDecimalPoint" numbers afterwards
		Local dotPos:Int = String(Long(tmp)).length  '+1
		If tmp < 0 Then dotPos :+ 1
		Local s:String = String(tmp)[.. dotPos + 1 + digitsAfterDecimalPoint]
		's = _StrLeft(string(tmp), dotPos + 1 + digitsAfterDecimalPoint)

		'remove 0s? 1.23000 => 1.23, 1.00 = 1
		If truncateZeros
			While s<>"" And _StrRight(s, 1) = "0"
				s = s[.. s.length-1]
			Wend
			'only "xx." left?
			If _StrRight(s, 1) = "." Then s = s[.. s.length-1]
		EndIf
		Return s
	End Function

Yours looks way more concise.

@thareh
Copy link
Contributor Author

thareh commented Mar 10, 2023

Hey,

Your solution looks very similar to my Blitzmax-based one I used before! 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants