Rounding to the nearest 1/16

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: Klaus, FourthWorld, heatherlaine, kevinmiller

Post Reply
cmhjon
Posts: 88
Joined: Tue Aug 04, 2015 11:55 am

Rounding to the nearest 1/16

Post by cmhjon » Mon Sep 28, 2020 9:23 pm

Hi everyone,

My math skills once again fail me. I need to have LC round a measurement UP to the nearest 1/16 of an inch. For example:

If the measurement is "4.333333333333333333" and it's rounded up it to the nearest 1/16 of an inch, the result would be 4.375 but because the measurement is closer to 4.3125, that's the result I get so how do I get LC to round UP every time?

My equation is:
put round(4.3333333333333333*16,0) / 16 into theMeasurement
Thank you,
Jon

Xero
Posts: 89
Joined: Sat Jun 23, 2018 2:22 pm

Re: Rounding to the nearest 1/16

Post by Xero » Tue Sep 29, 2020 4:49 am

I am sure there's an easier way of doing this...

Code: Select all

--have a field called 'field' that you put the measurement you want to round into.
put fld "field" into tMeasurement
--round that measurement either way--
put round(tMeasurement*16,0) / 16 into theFinalMeasurement
--check if the result is less than original- if so, it has rounded down. Then add 1/16 (or whatever you want) on to it so it goes to the next increment up.
if theFinalMeasurement < tMeasurement then put theFinalMeasurement + 0.0625 into theFinalMeasurement
--You might need to end if or exit if it's already rounded up. Then you can do whatever you want with theFinalMeasurement
Hope that helps.
XdM
Last edited by Xero on Tue Sep 29, 2020 10:49 am, edited 1 time in total.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7421
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Rounding to the nearest 1/16

Post by dunbarx » Tue Sep 29, 2020 4:57 am

Hi.

You have to fool LC into thinking out of the box. On a new card make a button and two fields. Put your decimal value into field 1. This can be any number at all. Put this into the button script:

Code: Select all

on mouseUp
   put roundOfSixteen(fld 1) into fld 2
end mouseUp

function roundOfSixteen var
   if var mod 0.0625 = 0 then return var
   else return round(var / 0.0625 + 0.5) * 0.0625
end roundOfSixteen
Craig
Last edited by dunbarx on Tue Sep 29, 2020 5:37 am, edited 1 time in total.

PBH
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 114
Joined: Sun Feb 20, 2011 4:26 pm
Location: Vancouver Island, BC, Canada. ex.UK
Contact:

Re: Rounding to the nearest 1/16

Post by PBH » Tue Sep 29, 2020 5:36 am

Not being an expert mathematician myself, I would just make a function, something like this.

Just used a button and 2 fields for testing.

Maybe there is a more elegant solution. :D

Code: Select all

on mouseUp pMouseButton
   put roundSixteenths(fld "input_Field") into fld "result_Field"
end mouseUp

function roundSixteenths pNumber
   put trunc(pNumber) * 16 into tSixteenths 
   put (pNumber - trunc(pNumber)) / 0.0625 into tRemainder
   add trunc(tRemainder) to tSixteenths
   if tRemainder - trunc(tRemainder) > 0 then add 1 to tSixteenths
   return tSixteenths / 16
end roundSixteenths

Or the shorter, but less readable version.

Code: Select all

function roundSixteenths pNumber
   put (trunc(pNumber) * 16) + trunc((pNumber - trunc(pNumber)) / 0.0625) into tSixteenths 
   if pNumber - (tSixteenths /16) > 0 then add 1 to tSixteenths
   return tSixteenths / 16
end roundSixteenths
P.S. I just tried Craig's solution, I thought of doing this initially, but if you input 4.375 it returns 4.4375 so you would need to change the line

Code: Select all

return round(var / 0.0625 + 0.5) * 0.0625
to something like

Code: Select all

return round(var / 0.0625 + 0.499999999) * 0.0625
It really depends on the amount of numbers behind the decimal point, using the round function like this could result in some errors, I'm sure they would be negligible, but for no errors at all, I think you will need to do the maths.

Paul

Opaquer
Posts: 247
Joined: Wed Aug 14, 2013 8:24 am

Re: Rounding to the nearest 1/16

Post by Opaquer » Tue Sep 29, 2020 7:06 am

Hey Jon

Could you use the ceiling function instead of round; something like this:

Code: Select all

on mouseUp
   put ceiling(measurement*16)/16 into roundedMeasurement
end mouseUp
With measurement being the decimal you want, and roundedMeasurement being the output? Basically, at the moment for 4.3333333333333333, when you *16, you end up with 69.33333333...

However, when you round it, LC will round to the closest number (with 0 decimal points as per your function), which in this case would be 69. Then when you do 69/16, you're going to be at 4.3125 like you said. However, the ceiling function will always round up to the next number, so 69.333333333333... will become 70, which when you divide by 16, you end up with 4.375 like you want. If you have a whole number after multiplying by 16, the ceiling function won't change it, leaving you with the same number you started with (for example starting with 4.375 will still yield 4.375)

Is that what you want from LC?

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7421
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Rounding to the nearest 1/16

Post by dunbarx » Tue Sep 29, 2020 2:32 pm

Craig here.
P.S. I just tried Craig's solution, I thought of doing this initially, but if you input 4.375 it returns 4.4375 so you would need to change the line
It does not for me. By inputting "4.375" I get the very same "4.375". How did you work it to get the extra sixteenth? This holds for any "perfect" decimal value of sixteenths, like "##.125" or "##.375".

On another note, I included the line:

Code: Select all

 if var mod 0.0625 = 0 then return var
because I assumed that an exact decimal representation of sixteenths was not required to round up, that it was already OK. If that is not true, that line needs to be removed.

Craig

EDIT:

My routine simply calculates the number of whole sixteenths (the number of "0.0625's) in the argument. This may leave a remainder, so it adds 0.5 so that the round function always goes up one. Then that same round function returns a value comprised of an integral number of sixteenths, expressed decimally.

PBH
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 114
Joined: Sun Feb 20, 2011 4:26 pm
Location: Vancouver Island, BC, Canada. ex.UK
Contact:

Re: Rounding to the nearest 1/16

Post by PBH » Tue Sep 29, 2020 5:02 pm

Hi Craig,

I just copied your original code into a button to test, but now I see how adding the "var mod" would fix the issue.

I knew somebody would come up with a more elegant solution, but in the end I guess Opaquer finally nailed a single line code with the ceiling function, I never thought of that, my attempt was more a hammer and chisel version. :D

Many ways to skin a 🐈 🙀

Paul

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7421
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Rounding to the nearest 1/16

Post by dunbarx » Tue Sep 29, 2020 5:17 pm

Paul.
I just copied your original code into a button to test, but now I see how adding the "var mod" would fix the issue.
Aha.

Yep, I had posted the one liner, and then realized I had not considered what was required for exact sixteenth values, so I added that other line with a comment. The ceiling function does indeed replace the need to bring the calculation past the halfway mark, an old, old trick dating back to HC days. Back then, I had a custom function called "roundUp" which did exactly that, forced rounding upwards regardless of the remainder value.

We, however, crossed in the eMail.

Craig

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”