Why can't round correctly using Math.round? - android

Why can't I round correctly this:
val solution = Math. round(iDouble * 10.00) / 10.00
Debugger says:
iDouble = 118.64300000000001
solution = 118.6

I dont see what is wrong with that. Here is the explanantion.
118.64300000000001d * 10L = 1186.43d
Math.round will return the number rounded to the integer part as an long.
Math.round(1186.43d) = 1186L.
1186L / 10.00d = 118.6d
So it looks fine to me. Keep in mind that dividing by a double/float will result in a double/float.

Related

Square Root formula in Calculator

Ok I am having an issue trying to put a square root equation in a calculator. I am trying to figure out the expression builder. I know the expression builder takes the math operations of add, subtract, multiply, divide, equals and the parenthesis. What I am doing is trying to build the square root section. I have a simple Percent code to help with the square root.
In the Square root vs the Percent you see I am using binding. So here is the code for both.
On the square root is it possible to use the expression builder? I know there is no absolute formula for square root except for a number that is multipliable with itself like the number 4.
Sqrt(4) = 2
binding.btnSqrt.setOnClickListener {
var square = (tv_equation.text.toString().toDouble() / 2)
binding.tvResult.text = square.toString()
}
So in the event you a non square equation
sqrt(23) = 4.79
How would I simulate that as one function within the button. Can I use expression or would I need to use Kotlin.math
So between the two I divide by 100 on the percent. It works great.
binding.btnPercent.setOnClickListener {
var percentage = (tv_equation.text.toString().toDouble() / 100)
binding.tvResult.text = percentage.toString()
}
All my other buttons work fine and so I am just working on the square root before I can release this to google play.
You would need to use some form of a square root function.
AS you mentioned in your question Kotlin Sqrt Function is a very suitable choice
binding.btnSqrt.setOnClickListener {
if(!tv_equation.text.isNullOrEmpty){
var number = tv_equation.text.toString().toDouble()
binding.tvResult.text = sqrt(number).toString()
}
You can create a sqrt function using the Quake's first inverse square root.
Quake's first inverse square root.
Pseudo Code:
float InvSqrt(float x){
float xhalf = 0.5f * x;
int i = *(int*)&x; // store floating-point bits in integer
i = 0x5f3759df - (i >> 1); // initial guess for Newton's method
x = *(float*)&i; // convert new bits into float
x = x*(1.5f - xhalf*x*x); // One round of Newton's method
return x;
}
So the answer i want to add is a little more suitable with the previous answer. Maybe this will help some people in the future. This solution will also limit the decimal space to 4 decimals.
binding.btnSqrt.setOnClickListener{
val df = DecimalFormat("#.####")
if(!tv_equation.text.isNullOrEmpty())
{
val number = tv_equation.text.toString().toDouble()
binding.tvResult.text = df.format(sqrt(number))
}
}
you can adjust the val df = DecimalFormat("#.####") where the # to as many decimals as you would want.

Why is Android Paint strokeWidth default value suddenly different?

Background
I have an app in the Google Play store built in Kotlin.
It currently displays a grid that the user draws her password on.
Here's a snapshot of the grid as it was previously drawn with the previous default paint.strokeWidth.
The grey lines between the (red) posts are drawn with the following method:
private fun DrawGridLines() {
val paint = Paint()
for (y in 0..numOfCells) {
xCanvas!!.drawLine(
(0 + leftOffset).toFloat(), (y * cellSize + topOffset).toFloat(),
(numOfCells * cellSize + leftOffset).toFloat(),
(y * cellSize + topOffset).toFloat(), paint
)
}
for (x in 0..numOfCells) {
xCanvas!!.drawLine(
(x * cellSize + leftOffset).toFloat(), (0 + topOffset).toFloat(),
(x * cellSize + leftOffset).toFloat(), (numOfCells * cellSize + topOffset).toFloat(),
paint
)
}
}
The Problem
While working on updates to the app I ran it on the emulator and saw the following:
As you can see the gridlines are drawn properly. Very odd since it seems to be drawing partial grid lines. NOTE: I ran this on numerous API versions and they all draw the grid lines this way now.
paint.strokeWidth = 0.0
I added some code to examine the value of paint.strokeWidth but that is additionally odd. It shows that the value of strokeWidth is always 0.0.
You can see that in my logcat output:
The Fix
Yes, I can simply fix this by explicitly setting the value myself.
I added the following line of code to the routine above:
paint.strokeWidth = 5F;
Now it looks like the following:
However, I'd like to know why this has suddenly occurred??
I'd also like to know how it seems to draw "some" of the lines since the value of the strokeWidth is actually 0.0???
The first thing I see in your code is that nowhere the Paint gets configured or its strokeWidth assigned a value. You need to set specific values and not use defaults, as defaults don't take into consideration display densities neither may have a valid usable value at all.
In the next sniped of your code you instantiate a new Paint instance and use it straight away without setting any properties to it:
private fun DrawGridLines() {
val paint = Paint()
for (y in 0..numOfCells) {
xCanvas!!.drawLine(....
"Here using already the new paint??? where did you configure it?"
Secondly, notice that Paint.strokeWidth units are in pixels, therefore you need to take into account the device display density and adjust to it.
for example:
val DEFAULT_SIZE_PX = 5.0f
val scaledWidth = DEFAULT_SIZE_PX * context
.resources
.displayMetrics
.density
paint.strokeWidth = scaledWidth
Or, which is the same as:
val DEFAULT_SIZE_PX = 5.0f
val displayMetrics = context.resources.displayMetrics
val scaledWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_SIZE_PX, displayMetrics)
paint.strokeWidth = scaledWidth
The official docs on setStrokeWidth provides a very interesting statement:
"Hairlines always draw a single pixel..."
I suppose the way that is handled is now probably handled differently and has this type of effect on output now. Or it is related to the density issue.
Either way, it is odd that it has changed. And interesting/odd that it states that you can set it to 0 for hairline output.

unexpected results (double vs float vs int)

i'm preforming a calculation (converting gigabytes to bytes) but i'm not get the expected results..i believe the calculations and logic is correct but i think it's the way i'm storing my number. i've played with using int, double, float and can't get the right format. i've set the text using toString, valueOf and String.format.
i'm getting 1.0737418E9 instead of 1073741824
relative code below: Thanks!
double sumB;
double sumG;
// get values
Bytes = (EditText)findViewById(R.id.numBytes);
Gigs = (EditText)findViewById(R.id.numGigs);
//calculations
sumB = Double.parseDouble(Gigs.getText().toString()) * 1073741824; //couldn'f figure out how to use exponents
sumG = Double.parseDouble(Gigs.getText().toString()) * 1;
//set text
//Bytes.setText(Integer.toString(sumB));
// Bytes.setText(Double.toString(sumB)); //didnt work
// Bytes.setText(String.format("%.8s", sumB)); //didnt work
Bytes.setText(String.valueOf(sumB));
Gigs.setText(Double.toString(sumG));

Add Toast in public class corresponding to any event

There all, i'm a newbie in android programming and i've a school task to analysis some project. So, i choose a Guitar Tuner project from github called pTune (link: here).
I've read the code and analyze it, from what i read and see there are a needle with an arc meter to see if the input sound (guitar voice) was fit.
In that project i want to display Toast if the tuning process are fit when the dial in 90 degree. So, i've add this Toast but its not displayed..
if (relativeFrequency == targetFrequency){
Toast.makeText(PTuneActivity.this, "FIT", Toast.LENGTH_SHORT).show();
}
That code placed in updateDisplay class, i've placed it in other class but still not work as i want.
public void updateDisplay(float frequency) {
// Calculate difference between target and measured frequency,
// given that the measured frequency can be a factor of target.
float difference = 0;
if (frequency > targetFrequency) {
int divisions = (int) (frequency / targetFrequency);
float modified = targetFrequency * (float) divisions;
if (frequency - modified > targetFrequency / 2) {
modified += targetFrequency;
divisions++;
}
difference = (frequency - modified) / (float) divisions;
} else {
// If target is greater than measured, just use difference.
difference = frequency - targetFrequency;
}
float relativeFrequency = targetFrequency + difference;
// Update TextView
if (relativeFrequency < 1000f)
t.setText(String.format("%.1f Hz", relativeFrequency));
else
t.setText(String.format("%.2f kHz", relativeFrequency/1000));
//My code
if (relativeFrequency == targetFrequency){
Toast.makeText(PTuneActivity.this, "FIT", Toast.LENGTH_SHORT).show();
}
// Update DialView
float value = difference / (targetFrequency / 2) * 90;
dial.update(value);
}
I know this is useless in real implementation but i want to learn android programming.
You're testing equality between 2 floats, one comes from an input ? It might never be exactly equal. You should add some log and an "else" statement to see if it goes inside the "if" because the Toast may not be the real problem
i've just try it by my self by digging and its worked for me, though its not good at all but i thinks ok, just add this line of code upper dial.update(value);
if (frequency >= targetFrequency) {
Toast.makeText(PTuneActivity.this, "FIT", Toast.LENGTH_SHORT).show();
}

Prismatic Joints for Box2d As3 won't work?

im trying to create a moving platform in box2d using prismatic joints, all that is created is a box and no joints are apparent, what am I doing wrong? Here is my code
var prismaticJoint:b2PrismaticJoint;
...
{
...
BodyDef.position.Set(0 / RATIO, 0 / RATIO);
floorDef.SetAsBox(250 / RATIO, 10 / RATIO);
fixtureDef.shape = floorDef;
fixtureDef.friction = 0.5;
fixtureDef.density = 0.5;
fixtureDef.restitution = 0;
movePlatformBody = PhysiVals.world.CreateBody(BodyDef);
movePlatformBody.CreateFixture(fixtureDef);
var prismaticJointDef:b2PrismaticJointDef = new b2PrismaticJointDef();
prismaticJointDef.Initialize(body, movePlatformBody, movePlatformBody.GetWorldCenter(), new b2Vec2(0,1));
prismaticJointDef.enableLimit = true;
prismaticJointDef.enableMotor = true;
prismaticJointDef.lowerTranslation = 0;
prismaticJointDef.maxMotorForce = 100;
prismaticJointDef.motorSpeed = 1;
prismaticJointDef.upperTranslation = 270 / PhysiVals.RATIO;
PhysiVals.world.CreateJoint(prismaticJointDef);
//prismaticJoint = PhysiVals.world.CreateJoint(prismaticJointDef as b2JointDef) as b2PrismaticJoint;
I tried 2 ways of creating it in the world, I dont know which one to use. How do I create a moving platform in box2d? Thank you for taking the time to read this.
Try modifying your initialize statement. Set the first parameter to the body that is going to move (the platform), set the second parameter to the static body (the world), and the third parameter will be the platforms centre.
I wrote a pretty popular tutorial on Box2D joints with an example of Prismatic Joints with source code so have a look at that too if you are still having problems
Tutorial.

Categories

Resources