Different results and codes for the discrete cosine transform... what is going on? - ios

I need to do a Discreet Cosine Transform of the following data:
0.6191342,0.6197224,0.61898607,0.61912596,0.6190106,0.61988443,0.61900085,0.6187835,0.6180295,0.61910814,0.6146555,0.6182434,0.6189235,0.61222005,0.6207976,0.6218684,0.62007576,0.6216523,0.6215335,0.62065303,0.6205161,0.61968786,0.619246,0.6213837,0.62122154,0.6192542,0.61824924,0.61987126,0.62156975,0.62128264,0.6205598,0.62057704,0.62053716,0.62275934,0.6218448,0.6203091,0.6178272,0.6140544,0.6213627,0.62143743,0.6132956,0.61910033,0.61519396,0.62216187,0.6215059,0.6197418,0.615724,0.62262917,0.62247676,0.62028235,0.6186407,0.619341,0.6152448,0.62161505,0.61356294,0.6133514,0.618384,0.6184519,0.6158993,0.6210517,0.61071134,0.62111616,0.61093444,0.62230366,0.6216592,0.61184555,0.61515874,0.6136047,0.6233515,0.618276,0.6159197,0.61444646,0.6185363,0.6162487,0.61572075,0.6194457,0.61314666,0.61829245,0.62141377,0.62105316,0.6124673,0.6179071,0.6186554,0.62159,0.61449164,0.61788505,0.6064126,0.6184563,0.6143939,0.6169126,0.61230534,0.6193385,0.6139966,0.6149371,0.6178339,0.61179554,0.6135024,0.61419034,0.614619,0.6137465,0.6185665,0.6185372,0.6163691,0.6195464,0.6170328,0.61263216,0.6161196,0.6184589,0.622137,0.61809236,0.61836344,0.61896133,0.6169496,0.6195432,0.6197563,0.61895114,0.61758405,0.61847824,0.61592484,0.6179055,0.61649424,0.61602193,0.6174835,0.61842364,0.60891753,0.61700743,0.6159329,0.61829287,0.6166717,0.6159072,0.6157982,0.6081088,0.6191729,0.61839896,0.615376,0.6154309,0.6119571,0.61734617,0.6171004,0.6178271,0.6169227,0.6172922,0.61745894,0.6195544,0.6103485,0.6142039,0.6166354,0.61975944,0.6184104,0.6177316,0.6150697,0.61001426,0.6108277,0.617212,0.6106007,0.61446583,0.61284953,0.6152104,0.6181612,0.61701053,0.6148785,0.61547005,0.62181646,0.618621,0.6161165,0.616407,0.6115453,0.6172732,0.61757433,0.61611485,0.61767805,0.61765575,0.61649793,0.6184486,0.6195102,0.61967367,0.6210996,0.61727804,0.6189702,0.6188129,0.6160338,0.6205609,0.6199804,0.6170756,0.6182058,0.61902076,0.62221605,0.6212938,0.61759907,0.6170265,0.6073142,0.6191233,0.61933994,0.61591357,0.6168009,0.6149173,0.6155775,0.6203353,0.6168877,0.61844844,0.60965574,0.61050487,0.62154305,0.62103915,0.6164665,0.6161686,0.60936993,0.614351,0.6204919,0.61622816,0.61612433,0.61211497,0.61347705,0.6192275,0.6165203,0.6156739,0.61536443,0.6136969,0.6195982,0.6201504,0.61684716,0.6125972,0.61233103,0.6179449,0.6163167,0.6089562,0.60863984,0.61114866,0.6104453,0.6166812,0.61086583,0.6118273,0.6211713,0.6160922,0.60824126,0.60837793,0.61538464,0.6222241,0.60950315,0.61592793,0.60851187,0.613283,0.61787575,0.6204593,0.6155273,0.6085147,0.6164997,0.61334276,0.61671215,0.6086348,0.6089769,0.61735654,0.6203436,0.60964227,0.6184011,0.6144072
If I use the Accelerate functions provided by Apple, I get these results:
2.669825,0.23372388,0.034602005,0.14609262,-0.05658116,0.028039198,-0.019894773,-0.12209733,0.022227166,0.0051003816,-0.042596065,-0.04589792,0.01035949,-0.019523097,0.077776365,0.0030713473,-0.078441024,-0.00070093106,0.01997262,0.06481835,-0.004874494,0.023854036,0.029294237,0.011619994,-0.0012118752,0.010400612,0.023407647,-0.05563956,0.038198948,-0.01233741,0.009424317,0.039608873,0.05801,0.028565174,-0.012889689,0.021731874,-0.026493106,-0.048108768,0.0045189788,-0.032068893,-0.017894993,-0.025662154,0.010751593,-0.07121442,0.06277961,0.0022988198,-0.018414639,-0.021932043,-0.020916257,-0.01747331,0.006716689,0.023302665,0.0068657864,-0.019596279,-0.043121584,0.04483221,-0.00012186449,-0.012160094,0.011104634,-0.015813472,0.023498433,0.02872037,0.014691476,0.015423553,-0.032783255,0.028947365,0.03251956,-0.016012289,-0.018248938,0.026564144,-0.034706548,0.012790314,0.002194486,0.04613065,-0.05747463,0.010088965,0.017059956,-0.04142371,-0.040067486,0.0029621175,0.07121314,-0.0064264582,-0.0064690933,-0.040944442,-0.0025974065,0.0075896196,-0.006084161,-0.027271878,0.056449506,-0.01756429,0.020225035,0.05740238,-0.07323427,0.091452986,-0.06606907,-0.00599443,0.03895919,0.0029399507,0.0050259903,-0.017262679,-0.052305933,0.0132182,-0.14926372,0.12026562,0.06996072,0.050748315,0.020096999,-0.017148953,0.006768549,-0.07308701,0.045742266,-0.055744015,0.034470245,-0.06591675,0.012785097,-0.045998022,0.028786233,-0.0006729504,0.026651034,0.016280383,-0.016419016,-0.0235405,-0.011106867,0.0060093636,-0.026253335,-0.020966358,0.049879722,-0.019093664,0.055243053,0.008216016,0.039922368,-0.05096092,0.010148679,-0.011200655,0.044212196,-0.012730424,0.027963173,-0.0050371652,0.0006729523,-0.02703674,-0.040479846,0.0032800399,0.019346198,0.03412081,-0.0062747486,-0.018566221,-0.011666842,0.02345107,-0.07089561,0.023972765,-0.0076217707,0.00794466,-0.008454496,-0.051500462,0.007845432,-0.046568125,-0.018137766,0.026703745,0.035737798,-0.061839998,-0.00884305,0.009104564,0.052314416,0.028979728,-0.017012393,-0.019422699,-0.049617197,0.03505949,0.005899897,0.031378012,0.02203784,0.05013973,-0.014152746,0.029270608,0.049914937,0.01226829,-0.038096413,0.012367716,-0.04856258,0.008609608,-0.014275378,-0.00032820972,0.003259441,0.04173329,0.0026449636,0.020232702,-0.058400147,0.006697319,-0.083465755,0.023861019,-0.019418886,-0.034204446,0.057170536,-0.03352673,-0.020436082,-0.024796713,-0.054371275,0.055950172,-0.01681035,0.018895034,0.042727623,0.040553555,-0.049501,0.003925497,-0.034148764,-0.00027683005,-0.054910377,0.03833572,0.053599093,0.02369698,-0.0021882567,0.04318303,0.0055106683,-0.026357781,-0.0022721058,-0.036762282,0.06495822,0.030521873,0.003908515,-0.052683424,-0.00785333,-0.0245375,-0.006546188,0.03067175,0.046067707,0.0047659995,-0.03191337,0.010508363,-0.0308632,-0.016877536,-0.05901345,0.0061260397,0.008024132,0.052667245,-0.026830386,0.021430418,-0.044398945,-0.02600174,-0.032572,0.06329122,0.032917332,0.0284806,-0.074899085,-0.025770163,-0.015752867,0.0030335134,0.04120659,0.0026583495,-0.005403653,0.009906204,0.029109228,0.015893774,0.0023716427,-0.02794688,-0.033177476,-0.08380169
If I use a code I call dctA I get this:
0.16686402,-0.235977,0.23596367,-0.23594144,0.23591036,-0.23587029,0.23582156,-0.23576365,0.23569722,-0.23562174,0.23553737,-0.2354442,0.23534207,-0.2352311,0.2351113,-0.23498271,0.23484512,-0.23469894,0.23454358,-0.2343797,0.2342069,-0.23402523,0.23383485,-0.23363559,0.2334273,-0.23321046,0.2329848,-0.23275039,0.23250724,-0.23225537,0.23199482,-0.2317253,0.23144716,-0.23116058,0.23086505,-0.23056087,0.23024791,-0.22992653,0.22959618,-0.22925732,0.22890992,-0.22855341,0.22818917,-0.22781523,0.22743407,-0.22704314,0.22664468,-0.22623657,0.22582,-0.225396,0.22496259,-0.22452155,0.22407113,-0.22361335,0.22314598,-0.22267129,0.22218716,-0.22169586,0.2211951,-0.22068696,0.22016953,-0.21964486,0.21911088,-0.21856976,0.21801907,-0.21746023,0.21689478,-0.21631947,0.21573758,-0.21514617,0.2145479,-0.2139403,0.2133261,-0.21270223,0.212072,-0.21143214,0.2107861,-0.21013027,0.20946832,-0.20879678,0.20811911,-0.20743181,0.20673671,-0.2060339,0.2053268,-0.20460844,0.20388247,-0.20314853,0.20241094,-0.20166187,0.20090508,-0.20014101,0.19937299,-0.19859369,0.19780688,-0.19701274,0.19621103,-0.19540597,0.19458961,-0.19376592,0.19293484,-0.19210072,0.19125515,-0.19040233,0.18954237,-0.18867959,0.18780532,-0.18692416,0.18603577,-0.1851449,0.18424252,-0.1833334,0.18241717,-0.1814941,0.18056883,-0.17963219,0.17868869,-0.1777385,0.17678645,-0.17582284,0.17485264,-0.17387584,0.1728974,-0.17190763,0.17091122,-0.1699084,0.16890429,-0.16788879,0.16686694,-0.16583884,0.16480431,-0.16376887,0.16272213,-0.16166915,0.16061012,-0.15955035,0.15847927,-0.15740223,0.15631929,-0.15523578,0.15414095,-0.15304045,0.15193413,-0.15082765,0.14970991,-0.14858656,0.1474576,-0.14632308,0.14518869,-0.14404319,0.14289224,-0.14173594,0.14057998,-0.13941304,0.13824077,-0.13706335,0.13588662,-0.1346989,0.13350609,-0.13230827,0.13111141,-0.12990372,0.12869103,-0.12747958,0.12625119,-0.1250302,0.12379233,-0.122562,0.121327065,-0.120075285,0.118831374,-0.11758294,0.11631756,-0.11506039,0.11378633,-0.112520546,0.11125048,-0.10996368,0.10868541,-0.10739021,0.10610382,-0.104813375,0.10350613,-0.102208,0.100905985,-0.09958719,0.098277606,-0.096951276,0.09563441,-0.09431398,0.092976734,-0.09164931,0.090305135,-0.088970825,0.087633155,-0.086278856,0.08493474,-0.08358737,0.08222347,-0.0808699,0.079499744,-0.07814017,0.07677769,-0.07539867,0.07403045,-0.07265948,0.07127206,-0.069895685,0.0685029,-0.06712131,0.06573725,-0.06433683,0.062947854,-0.061542634,0.06014901,-0.05875311,0.057341076,-0.055940807,0.054538473,-0.053120058,0.05171367,-0.05029129,0.048881073,-0.047469016,0.046041086,-0.044625536,0.043194164,-0.041775327,0.0403549,-0.038918786,0.0374954,-0.03607061,0.03463024,-0.033202793,0.031759836,-0.030329958,0.028898928,-0.027452547,0.026019417,-0.024585323,0.02313597,-0.021700067,0.020249018,-0.018811548,0.017373376,-0.015920186,0.014480768,-0.013026423,0.0115859695,-0.0101450775,0.00868942,-0.0072478293,0.0058059655,-0.0043494827,0.0029072375,-0.0014504795
and if I use another code I have found on the web, that I call dctB I get this:
0.23598135,0.0065520015,-0.0014035295,-0.0014900116,-0.0029997544,-0.0022787564,0.003723558,-0.003108655,-0.0012933733,-0.0007105355,0.0012699091,-0.00060556503,0.0053185527,0.00076327357,-0.0011331664,0.005722867,0.0034567474,-0.0011424342,-0.0013203556,0.0021249577,-0.0029971765,0.0006293817,0.0019937858,0.0026412704,0.00016487329,-0.003959481,0.00039281833,-0.0024429162,0.00060916966,-0.0019161169,-0.006625204,-0.002263753,0.00040166255,-0.0013965253,-0.00019885821,-0.010229679,0.0015206567,-0.0053624627,0.00058637373,0.0070882766,-0.0044516595,0.0010087036,-0.0064169616,0.0043392666,0.0012746729,0.0014619434,-0.0050648195,0.0009482073,0.004468296,-0.0015502489,-0.0043041282,-0.001236145,0.0048462045,-0.003547573,0.0035744759,0.0021012123,0.0039755865,0.0017270996,-0.0047634826,0.0021218802,0.003715937,-0.0038134162,-0.0031784503,0.0021606751,0.0063801087,-6.5251596e-05,-0.004479158,-0.0052841934,0.0056381524,0.0003858073,-0.00277002,0.001508747,0.005996452,-0.0019169269,0.001555898,0.00014130188,0.005808804,0.0037767508,-0.0026520337,-0.0018158474,0.0033173792,0.0046277773,-0.0006036768,-0.0019087599,9.9361154e-05,0.004506388,-0.0044565895,0.00051484356,-0.0026925507,0.005224032,8.564865e-05,-0.0057873107,-0.000118939184,-0.0065063527,0.004078492,0.0003850522,-0.0038591337,0.0016885462,-0.0028994652,0.00063551,0.0018036738,-0.0020673752,-1.50109045e-05,0.0007685168,-0.0028343478,0.003231319,0.0062061716,0.0032275403,-0.002344687,0.000663079,-0.0016223937,-0.0045130113,0.0058470825,0.00283345,-0.0020404255,-9.103818e-05,0.004184909,-0.003951648,-0.00038761974,0.0010700208,-0.0066716103,-0.00018829755,0.0036042533,-0.0043730726,-0.002380092,0.0013307306,-0.0021570993,0.007163353,0.16732568,0.0021171984,0.00011411852,-0.00347561,-0.0018730971,0.0011592627,0.0017720436,-0.0042686476,0.004867761,-0.002120747,0.002259214,0.003109498,0.0034014524,0.0012342912,0.00042545033,0.005238078,-0.0009351839,0.0028766692,-0.0002561589,0.0023975722,-0.0019213242,-0.0023478842,-0.0033766865,0.0005857277,0.0030684788,-0.006383024,0.00048669687,-0.0014512719,-0.0009451752,-0.0033242197,-0.006483069,-0.004888436,0.00435442,-0.0022291946,-0.0043107485,-0.007959526,0.0022944517,-0.0017021666,0.000734793,0.0049511404,-0.003661971,0.00094925304,-0.004634777,0.0016841891,0.0016499859,0.003999946,-0.0065253885,-0.0033514274,0.003085088,-0.0003703781,-0.003465078,-0.0054242075,0.0009584457,-0.005197831,0.003603162,0.0048823943,-0.00041171763,0.0009989656,-0.0040209224,0.002628903,-0.0003624089,-0.0002924401,-3.2498552e-05,0.0031572247,0.0026128257,-0.0022803256,-0.0030580086,-0.00357484,0.0042991657,-0.0015585661,0.00086751115,0.0004323435,0.0045290007,-0.0048501627,-0.001418146,0.00370478,0.003376496,0.006685608,0.00055006717,-0.0011108073,0.00024791225,0.0055819694,0.0041101393,-0.0041453117,-0.0011638473,0.0020769653,-8.08032e-06,-0.0002288826,0.0006749544,0.00035142386,-0.00043356852,-0.0029805794,-0.0017968996,0.0010227,0.006042389,0.0017817094,-0.0056505343,0.004619073,0.0023046366,0.0027151196,0.0020018944,-0.00041239324,-0.00031199362,0.0050316383,-0.0041035055,0.001887646,0.0069080763,0.0039198315,-0.0003352705,-0.0012968663,-0.0009449865,-0.0052614617,0.004834936,-0.0014728566,-0.0017496345,-0.0008812858,0.00056978094,-0.005053855,-0.0017934664,0.0021964775,-0.008228115,0.0029420764,0.0012297969,-0.0038868873,-0.0003670447,0.0032279065,-0.0016167451,0.0036267326
These are the 3 codes in order:
let DCTSetupForward = vDSP_DCT_CreateSetup(nil,
vDSP_Length(numberSamples),
vDSP_DCT_Type.II)
var output = Array<Float>(repeating:0.0,
count: numberSamples)
vDSP_DCT_Execute(DCTSetupForward!, data, &output)
func dctA (_ data:[Float] = []) -> Array<Float> {
let numberSamples = data.count
var c = [Float](repeating: 0,
count: numberSamples)
for i in 0..< numberSamples {
var sum : Float = 0
let s : Float = (i == 0) ? sqrt(0.5) : 1
for j in 0..< numberSamples {
sum = sum + s * data[j] * cos(Float.pi * (numberSamples + 0.5) * Float(i) / numberSamples)
}
c[i] = sum * sqrt(2.0 / numberSamples)
}
return c;
}
func dctB (_ data:[Float] = []) -> Array<Float> {
var angle : Float
var c :[Float] = []
let numberSamples = data.count
for i in 0..<numberSamples {
c.append(0)
for j in 0..< numberSamples {
let fk = Float(2*j + 1)
let y = Float.pi * Float(i) * fk
let fky = fk * y
let x = Float(2 * numberSamples)
angle = fky / x
c[i] = c[i] + cos ( angle ) * data[j];
}
c[i] = c[i] * sqrt (2.0/Float(numberSamples));
}
return c;
}
I have noticed the difference in the two last codes. So, I have 3 questions:
Why am I having 3 different results for the DCT of this data?
Can someone with mathlab check which is the right one?
why the difference in the last two codes?

Searching through Wikipedia and the formula of the above are different for typeII.
If you following the corrected one below, the error mainly comes from rounding during multiplying and summation.
let DCTSetupForward = vDSP_DCT_CreateSetup(nil,
vDSP_Length(numberSamples),
vDSP_DCT_Type.II)
var output = Array<Float>(repeating:0.0,
count: numberSamples)
vDSP_DCT_Execute(DCTSetupForward!, data, &output)
print(output)
func dctA (_ data:[Float] = []) -> Array<Float> {
let numberSample = data.count
var c = [Float](repeating: 0,
count: numberSample)
for i in 0..<numberSample {
var sum : Float = 0
let s : Float = (i == 0) ? 1 : 1
for j in 0..<numberSample {
sum = sum + s * data[j] * cos(Float.pi * (Float(j) + 0.5) * Float(i) / Float(numberSample))
}
c[i] = sum
}
return c;
}
func dctB (_ data:[Float] = []) -> Array<Float> {
var angle : Float
var c :[Float] = []
let numberSampl = data.count
for i in 0..<numberSampl {
c.append(0)
for j in 0..<numberSampl {
let fk = Float(2*j + 1)
let y = Float.pi * Float(i) * fk
// let fky = fk * y
let x = Float(2 * numberSampl)
angle = y / x
c[i] = c[i] + cos ( angle ) * data[j];
}
}
return c;
}

Related

Calculating total price present in shopping cart

is how my shopping cart looks like..
I am trying to calculate the subtotal price based on the products present in the cart dynamically. My code is here :
func displaySubTotal() {
if cartArray.count == 1 {
let p1 = Double(cartArray[0].cartItems.price)
let p2 = Double(cartArray[0].cartQuantity)
let p = Double(p1! * p2)
let x1 = Double(p)
subtotalPrice.text = "\(x1)"
}
if cartArray.count == 2 {
let p1 = Double(cartArray[0].cartItems.price)
let p2 = Double(cartArray[0].cartQuantity)
let p = Double(p1! * p2)
let q1 = Double(cartArray[1].cartItems.price)
let q2 = Double(cartArray[1].cartQuantity)
let q = Double(q1! * q2)
let x2 = Double(p + q)
subtotalPrice.text = "\(x2)"
}
if cartArray.count == 3 {
let p1 = Double(cartArray[0].cartItems.price)
let p2 = Double(cartArray[0].cartQuantity)
let p = Double(p1! * p2)
let q1 = Double(cartArray[1].cartItems.price)
let q2 = Double(cartArray[1].cartQuantity)
let q = Double(q1! * q2)
let r1 = Double(cartArray[2].cartItems.price)
let r2 = Double(cartArray[2].cartQuantity)
let r = Double(r1! * r2)
let x3 = Double(p + q + r)
subtotalPrice.text = "\(x3)"
}
if cartArray.count == 4 {
let p1 = Double(cartArray[0].cartItems.price)
let p2 = Double(cartArray[0].cartQuantity)
let p = Double(p1! * p2)
let q1 = Double(cartArray[1].cartItems.price)
let q2 = Double(cartArray[1].cartQuantity)
let q = Double(q1! * q2)
let r1 = Double(cartArray[2].cartItems.price)
let r2 = Double(cartArray[2].cartQuantity)
let r = Double(r1! * r2)
let s1 = Double(cartArray[3].cartItems.price)!
let s2 = Double(cartArray[3].cartQuantity)
let s = Double(s1 * s2)
let x4 = Double(p + q + r + s)
subtotalPrice.text = "\(x4)"
}
if cartArray.count == 5 {
let p1 = Double(cartArray[0].cartItems.price)
let p2 = Double(cartArray[0].cartQuantity)
let p = Double(p1! * p2)
let q1 = Double(cartArray[1].cartItems.price)
let q2 = Double(cartArray[1].cartQuantity)
let q = Double(q1! * q2)
let r1 = Double(cartArray[2].cartItems.price)
let r2 = Double(cartArray[2].cartQuantity)
let r = Double(r1! * r2)
let s1 = Double(cartArray[3].cartItems.price)!
let s2 = Double(cartArray[3].cartQuantity)
let s = Double(s1 * s2)
let t1 = Double(cartArray[4].cartItems.price)!
let t2 = Double(cartArray[4].cartQuantity)
let t = Double(t1 * t2)
let x5 = Double(p + q + r + s + t)
subtotalPrice.text = "\(x5)"
}
}
But I can't make it dynamic (price is needed to be updated with the delete of products instantly & addition/subtraction of quantity [using the (+ & -) buttons] of products). I'm trying this kind of thing for the first time. Please suggest me hoe to solve this! Thanks in advance..
Just loop over your cart items. (item_price * quantity)
func displaySubTotal() {
var total_price: Float = 0.0
for items in cartArray {
if let price = Float(items.cartItems.price) {
total_price += Float(items.cartQuantity) * price
}
}
subtotalPrice.text = "\(total_price)"
}
#objc func add(sender: UIButton) {
if cartArray[sender.tag].cartQuantity >= 0 {
cartArray[sender.tag].cartQuantity += 1
cartTableView.reloadData()
self.displaySubTotal()
}
}
#objc func sub(sender: UIButton) {
if cartArray[sender.tag].cartQuantity > 0 {
cartArray[sender.tag].cartQuantity -= 1
cartTableView.reloadData()
self.displaySubTotal()
}
}

Concatenate Int like String in Swift?

I need Something like
var a = 1
var b = 2
var c = a + b should be 12 (Int) instead of 3.
var a = 12
var b = 34
var c = a + b should be 1234 (Int) instead of 46.
I am not figuring out how can we do this for any number?
One way is to convert two both Int to String, concatenate and covert it again that String to Int, but I don't think it's efficient.
Thank you in advance if you have a solution.
You can do it with simple conversion like below:
var a = 1
var b = 2
var c = Int("\(a)\(b)") // Result 12
var a1 = 12
var b1 = 34
var c1 = Int("\(a1)\(b1)") // Result 1234
var a2 = 122344
var b2 = 9022
var c2 = Int("\(a2)\(b2)") // Result 1223449022
12+34 = 12*10^2 + 34 = 1200+34 = 1234
func logC(val: Double, forBase base: Double) -> Double {
return log(val)/log(base)
}
var a = 10
var b = 0
let x = b == 10 ? 2 : b == 0 ? 1 : ceil(logC(val: Double(b), forBase: 10))
var c = Int(Double(a) * pow(10, x) + Double(b))
print(c)
You can write something like this:
extension Int {
func concatenateDecimalDigits(in other: Int) -> Int {
let scale: Int
switch other {
case 0...9:
scale = 10
case 10...99:
scale = 100
case 100...999:
scale = 1000
case 1000...9999:
scale = 10000
case 10000...99999:
scale = 100000
case 100000...999999:
scale = 1000000
//You need to add more cases if you need...
//...
//...
default:
scale = 0 //ignore invalid values
}
return self * scale + other
}
}
var a = 1
var b = 2
print( a.concatenateDecimalDigits(in: b) ) //->12
a = 12
b = 34
print( a.concatenateDecimalDigits(in: b) ) //->1234
a = 122344
b = 9022
print( a.concatenateDecimalDigits(in: b) ) //->1223449022
You can write some logic to calculate scale without switch, but that does not make much difference.
General solution for any two Int:
You will need to calculate number of digits for calculate multiplier as:
func numberOfDigits(_ num: Int) -> Int {
var count = 0
var number = num
while number > 0 {
number = number / 10
count += 1
}
return count
}
Use it as:
let a = 11
let b = 24
let noOfDigit = numberOfDigits(b)
let multiplier = pow(Double(10), Double(noOfDigit))
let c = a * Int(multiplier) + b
print(c)
And, in one line as:
let c = a * Int(pow(Double(10), Double(numberOfDigits(b)))) + b

Are pointers to Objective-C arrays (via a bridging header) allowed?

I have been trying to get the GLCameraRipple sample from Apple running in a swift project. Unfortunately this relies heavily on using C style, thread-safe arrays only available in Objective-C.
I have been trying to use a bridging header so that the simulation can run in Objective-C code, and the drawing can run in swift code. That way the thread-safe thing would not be an issue.
I have taken the Objective-C code and translated it almost completely into swift with a few exceptions. I did cull some of the extra math since the texture is the same size as the screen for my needs. If you want to check my translation I have put them below.
Anyway I have made a class that will run in any xcode project with an opengl environment.
import Foundation
import GLKit
import OpenGLES
class WaterDrawer
{
static var sim = RippleModel()
static var shade = Shader("Shader2")
static func pt(pt: CGPoint)
{
sim.initiateRippleAtLocation(pt)
}
static func firstStart(width: Int, height: Int)
{
sim.initWithScreenWidth(width / 4, iheight: height / 4, accWidth: width, accHeight: height)
shade.begin()
buildMatrix(width, height: height)
bufferSetup()
}
static func draw()
{
glUseProgram(shade.progId)
let posLoc = GLuint(glGetAttribLocation(shade.progId, "pos"))
let texLoc = GLuint(glGetAttribLocation(shade.progId, "tc"))
glBindBuffer(GLenum(GL_ARRAY_BUFFER), texVBO);
glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(sim.getVertexSize()), sim.getTexCoords(), GLenum(GL_DYNAMIC_DRAW));
glVertexAttribPointer(texLoc, 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, BUFFER_OFFSET(0))
glEnableVertexAttribArray(texLoc)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), posVBO)
glVertexAttribPointer(posLoc, 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, BUFFER_OFFSET(0))
glEnableVertexAttribArray(posLoc)
let uniOrtho = glGetUniformLocation(shade.progId, "matrix")
glUniformMatrix4fv(uniOrtho, 1, GLboolean(GL_FALSE), &orthographicMatrix)
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indVBO)
glDrawElements(GLenum(GL_TRIANGLE_STRIP), GLsizei(sim.getIndexCount()), GLenum(GL_UNSIGNED_SHORT), nil)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), 0)
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), 0)
glDisableVertexAttribArray(posLoc)
glDisableVertexAttribArray(texLoc)
}
static func update()
{
sim.runSimulation()
}
static var posVBO:GLuint = 0
static var texVBO:GLuint = 0
static var indVBO:GLuint = 0
static func bufferSetup()
{
Whirl.crashLog("Started passing in buffer data")
glGenBuffers(1, &indVBO);
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indVBO);
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), GLsizeiptr(sim.getIndexSize()), sim.getIndices(), GLenum(GL_STATIC_DRAW));
glGenBuffers(1, &posVBO);
glBindBuffer(GLenum(GL_ARRAY_BUFFER), posVBO);
glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(sim.getVertexSize()), sim.getVertices(), GLenum(GL_STATIC_DRAW));
glGenBuffers(1, &texVBO);
glBindBuffer(GLenum(GL_ARRAY_BUFFER), texVBO);
glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(sim.getVertexSize()), sim.getTexCoords(), GLenum(GL_DYNAMIC_DRAW));
Whirl.crashLog("Finished passing in buffer Data")
}
static var orthographicMatrix:[GLfloat] = []
static func buildMatrix(width: Int, height: Int)
{
orthographicMatrix = glkitmatrixtoarray(GLKMatrix4MakeOrtho(0, GLfloat(width), 0, GLfloat(height), -100, 100))
//Storage.upScaleFactor
}
static func glkitmatrixtoarray(mat: GLKMatrix4) -> [GLfloat]
{
var buildme:[GLfloat] = []
buildme.append(mat.m.0)
buildme.append(mat.m.1)
buildme.append(mat.m.2)
buildme.append(mat.m.3)
buildme.append(mat.m.4)
buildme.append(mat.m.5)
buildme.append(mat.m.6)
buildme.append(mat.m.7)
buildme.append(mat.m.8)
buildme.append(mat.m.9)
buildme.append(mat.m.10)
buildme.append(mat.m.11)
buildme.append(mat.m.12)
buildme.append(mat.m.13)
buildme.append(mat.m.14)
buildme.append(mat.m.15)
return buildme
}
}
So theoretically this code can use either the swift implementation or the Objective-C implementation, I just need to switch the way the mesh is initiated.
Trouble is when I use the Objective-C one the screen is blank, I have checked, and the buffer data looks really weird in the frame capture.
Are you allowed to pass in data from an Objective-C code to a glBuffer?
Simulation.swift
import Foundation
import GLKit
import OpenGLES
class RippleModel
{
var screenWidth:UInt32 = 0
var screenHeight:UInt32 = 0
var poolWidth:UInt32 = 0
var poolHeight:UInt32 = 0
var screenWidthi:Int = 0
var screenHeighti:Int = 0
var poolWidthi:Int = 0
var poolHeighti:Int = 0
let touchRadius:Int = 5 //5 i think
var rippleVertices:[GLfloat] = []
var rippleTexCoords:[GLfloat] = []
var rippleIndices:[GLushort] = []//NOTE IF CHANGE THIS TO INTO SO MUCH DRAW CALL
var rippleSource:[GLfloat] = []
var rippleDest:[GLfloat] = []
var rippleCoeff:[GLfloat] = []
var VertexSize:GLsizeiptr = 0
var IndicieSize:GLsizeiptr = 0
var IndicieCount:Int = 0
func calculateSizes()
{
VertexSize = rippleVertices.count * sizeof(GLfloat)
IndicieSize = rippleIndices.count * sizeof(GLushort)
IndicieCount = rippleIndices.count
Whirl.crashLog("Data sizes Vertex size \(VertexSize)\tIndicie Size \(IndicieSize) \tIndicie Count \(IndicieCount)")
}
func figureOutCoefficent()
{
for y in 0...(2 * touchRadius)
{
for x in 0...(2 * touchRadius)
{
let dx = x - touchRadius
let dy = y - touchRadius
let distance = sqrt(GLfloat(dx * dx + dy * dy))
let me = y * (touchRadius*2 + 1) + x
if (distance <= GLfloat(touchRadius))
{
let factor = distance / GLfloat(touchRadius)
rippleCoeff[me] = -(cos(factor*GLfloat(M_PI))+1.0) * 256.0;
}
else
{
rippleCoeff[me] = 0.0
}
}
}
}
init()
{
}
func initWithScreenWidth( iwidth: Int, iheight: Int, accWidth: Int, accHeight: Int)
{
screenWidth = UInt32(accWidth);screenWidthi = Int(screenWidth)
screenHeight = UInt32(accHeight);screenHeighti = Int(screenHeight)
poolWidth = UInt32(iwidth);poolWidthi = Int(poolWidth)
poolHeight = UInt32(iheight);poolHeighti = Int(poolHeight)
//WE DONT NEED TEX COORD MUMBO JUMBO IT IS FULL SCREEN ALREADY
Whirl.crashLog("Started allocation")
rippleCoeff = [GLfloat](count: Int( (touchRadius * 2 + 1) * (touchRadius*2 + 1) ), repeatedValue: 0)
figureOutCoefficent()
let simCount:Int = Int(poolWidth + 2) * Int(poolHeight + 2)
rippleSource = [GLfloat](count: simCount, repeatedValue: 0)
rippleDest = [GLfloat](count: simCount, repeatedValue: 0)
let locb:Int = Int(poolWidth * poolHeight * 2)
rippleVertices = [GLfloat](count: locb, repeatedValue: 0)
rippleTexCoords = [GLfloat](count: locb, repeatedValue: 0)
rippleIndices = [GLushort](count: Int(poolHeight - 1) * Int((poolWidth * 2) + 2), repeatedValue: 0)
Whirl.crashLog("Finished allocation")
initMesh()
calculateSizes()
}
func initMesh()
{
Whirl.crashLog("Started initting pos coords")
for i in 0..<poolHeight
{let ii = GLfloat(i)
for j in 0..<poolWidth
{let jj = GLfloat(j)
let cordb:Int = Int(i*poolWidth+j)*2
rippleVertices[cordb + 0] = (jj / GLfloat(poolWidth - 1)) * GLfloat(screenWidth)
rippleVertices[cordb + 1] = (ii / GLfloat(poolHeight - 1)) * GLfloat(screenHeight)
rippleTexCoords[cordb + 0] = ii / GLfloat(poolHeight - 1)
rippleTexCoords[cordb + 1] = (jj/GLfloat(poolWidth - 1))
}
}
Whirl.crashLog("Finished initting pos coords")
Whirl.crashLog("Started initting index coords")
var index = 0
for i in 0 ..< poolHeighti-1
{
for j in 0 ..< poolWidthi
{
if (i%2 == 0)
{
// emit extra index to create degenerate triangle
if (j == 0)
{
rippleIndices[index] = GLushort(i*poolWidthi+j);
index += 1;
}
rippleIndices[index] = GLushort(i*poolWidthi+j);
index += 1;
rippleIndices[index] = GLushort((i+1)*poolWidthi+j);
index += 1;
// emit extra index to create degenerate triangle
if (j == (poolWidthi-1))
{
rippleIndices[index] = GLushort((i+1)*poolWidthi+j);
index += 1;
}
}
else
{
// emit extra index to create degenerate triangle
if (j == 0)
{
rippleIndices[index] = GLushort((i+1)*poolWidthi+j);
index += 1;
}
rippleIndices[index] = GLushort((i+1)*poolWidthi+j);
index += 1;
rippleIndices[index] = GLushort(i * poolWidthi + j);
index += 1;
// emit extra index to create degenerate triangle
if (j == (poolWidthi-1))
{
rippleIndices[index] = GLushort(i * poolWidthi + j);
index += 1;
}
}
}
}
Whirl.crashLog("Finished initting coords")
}
var firstUpdate = true
func runSimulation()
{
if (firstUpdate)
{firstUpdate = false; Whirl.crashLog("First update")}
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
//dispatch_apply(Int(poolHeight), queue, {(y: size_t) -> Void in
for y in 0..<poolHeighti {
let pw = self.poolWidthi
for x in 1..<(pw - 1)
{
let ai:Int = (y ) * (pw + 2) + x + 1
let bi:Int = (y + 2) * (pw + 2) + x + 1
let ci:Int = (y + 1) * (pw + 2) + x
let di:Int = (y + 1) * (pw + 2) + x + 2
let me:Int = (y + 1) * (pw + 2) + x + 1
let a = self.rippleSource[ai]
let b = self.rippleSource[bi]
let c = self.rippleSource[ci]
let d = self.rippleSource[di]
var result = (a + b + c + d) / 2.0 - self.rippleDest[me]
result -= result / 32.0
self.rippleDest[me] = result
}
}
//)
let hm1 = GLfloat(poolHeight - 1)
let wm1 = GLfloat(poolWidth - 1)
//dispatch_apply(poolHeighti, queue, {(y: size_t) -> Void in
for y in 0..<poolHeighti{
let yy = GLfloat(y)
let pw = self.poolWidthi
for x in 1..<(pw - 1)
{let xx = GLfloat(x)
let ai:Int = (y ) * (pw + 2) + x + 1
let bi:Int = (y + 2) * (pw + 2) + x + 1
let ci:Int = (y + 1) * (pw + 2) + x
let di:Int = (y + 1) * (pw + 2) + x + 2
let a = self.rippleDest[ai]
let b = self.rippleDest[bi]
let c = self.rippleDest[ci]
let d = self.rippleDest[di]
var s_offset = ((b - a) / 2048)
var t_offset = ((c - d) / 2048)
s_offset = (s_offset < -0.5) ? -0.5 : s_offset;
t_offset = (t_offset < -0.5) ? -0.5 : t_offset;
s_offset = (s_offset > 0.5) ? 0.5 : s_offset;
t_offset = (t_offset > 0.5) ? 0.5 : t_offset;
let s_tc = yy / hm1
let t_tc = xx / wm1
let me = (y * pw + x) * 2
self.rippleTexCoords[me + 0] = s_tc + s_offset
self.rippleTexCoords[me + 1] = t_tc + t_offset
}
}
//)
let pTmp = rippleDest
rippleDest = rippleSource
rippleSource = pTmp
}
var firstRipple:Bool = true
func initiateRippleAtLocation(location: CGPoint)
{
if (firstRipple)
{firstRipple = false; Whirl.crashLog("First ripple placement")}
let xIndex = Int((GLfloat(location.x) / GLfloat(screenWidth)) * GLfloat(poolWidthi))
let yIndex = Int((1.0 - (GLfloat(location.y) / GLfloat(screenHeighti))) * GLfloat(poolHeight))
let lowy = yIndex - touchRadius
let highy = yIndex + touchRadius
let lowx = xIndex - touchRadius
let highx = xIndex + touchRadius
//Whirl.crashLog("Ripple at (\(xIndex) , \(yIndex))\tX:(\(lowx) - \(highx))\tY:(\(lowy) - \(highy))")
for y in lowy...highy
{
for x in lowx...highx
{
if (x > 0 && x < (poolWidthi - 1) && y > 0 && y < poolHeighti)
{
let ind = (poolWidthi + 2) * (y + 1) + x + 1
let coef = (y-(yIndex-touchRadius))*(touchRadius*2+1)+x-(xIndex-touchRadius)
let past = rippleSource[ind]
let coe = rippleCoeff[coef]
if (coe < past)
{
rippleSource[ind] = coe
}
}
}
}
}
func rippleLine(location1: CGPoint, location2: CGPoint)
{
if (firstRipple)
{firstRipple = false; Whirl.crashLog("First ripple placement")}
let xIndex1 = Int((GLfloat(location1.x) / GLfloat(screenWidth)) * GLfloat(poolWidthi))
let yIndex1 = Int((1.0 - (GLfloat(location1.y) / GLfloat(screenHeighti))) * GLfloat(poolHeight))
let xIndex2 = Int((GLfloat(location2.x) / GLfloat(screenWidth)) * GLfloat(poolWidthi))
let yIndex2 = Int((1.0 - (GLfloat(location2.y) / GLfloat(screenHeighti))) * GLfloat(poolHeight))
let lowy1 = yIndex1 - touchRadius
let highy1 = yIndex1 + touchRadius
let lowx1 = xIndex1 - touchRadius
let highx1 = xIndex1 + touchRadius
let lowy2 = yIndex2 - touchRadius
let highy2 = yIndex2 + touchRadius
let lowx2 = xIndex2 - touchRadius
let highx2 = xIndex2 + touchRadius
let lowx = min(lowx1, lowx2)
let highx = max(highx1, highx2)
let lowy = min(lowy1, lowy2)
let highy = max(highy1, highy2)
for y in lowy...highy
{
for x in lowx...highx
{
if (x > 0 && x < (poolWidthi - 1) && y > 0 && y < poolHeighti)
{
let ind = (poolWidthi + 2) * (y + 1) + x + 1
let tar = ldist(CGPoint(x: xIndex1, y: yIndex1), p2: CGPoint(x: xIndex2, y: yIndex2), me: CGPoint(x: x, y: y))
let dx = x - Int(tar.x)
let dy = y - Int(tar.y)
let distq = (dx * dx + dy * dy)
if (distq < touchRadius * touchRadius)
{
let factor = sqrt(GLfloat(distq)) / GLfloat(touchRadius)
rippleSource[ind] = -(cos(factor*GLfloat(M_PI))+1.0) * 256.0;
}
//rippleSource[ind] = 1000
}
}
}
}
func ldist(p1: CGPoint, p2: CGPoint, me: CGPoint) -> CGPoint
{
let diffX = p2.x - p1.x
let diffY = p2.y - p1.y
var target = CGPoint()
if ((diffX == 0) && (diffY == 0))
{
target = p1
}
let t = ((me.x - p1.x) * diffX + (me.y - p1.y) * diffY) / (diffX * diffX + diffY * diffY)
if (t < 0)
{
target = p1
}
else if (t > 1)
{
target = p2
}
else
{
target = CGPoint(x: (p1.x + t * diffX), y: (p1.y + t * diffY))
}
let int = CGPoint(x: round(target.x), y: round(target.y))
return int
}
func getVertices() -> [GLfloat]
{
//Return the mesh positions
return rippleVertices
}
func getTexCoords() -> [GLfloat]
{
//Return the array of texture coords
return rippleTexCoords
}
func getIndices() -> [GLushort]
{
//Return the array of indices
return rippleIndices
}
func getVertexSize() -> GLsizeiptr
{
//Return the size of the mesh position array
return VertexSize
}
func getIndexSize() -> GLsizeiptr
{
//Return the byte size of the incicie array
return IndicieSize
}
func getIndexCount() -> GLsizeiptr
{
//This goes in the draw call, count of indices
return IndicieCount
}
}
RippleModel.m (from apple)
Are you allowed to pass in data from an objective-c code to a glBuffer?
Why wouldn't you be allowed? Swift has a pointer API (UnsafePointer<T>, UnsafeMutablePointer<T>, etc.) exactly for this purpose. Obviously this is "unsafe" in the sense that the underlying memory the [Objective-]C pointer points to could change at anytime without the Swift pointer knowing. It also has no information about the size of the memory block that it points to.
Any C pointers or arrays can be bridged to Swift (probably as UnsafeMutablePointer<Void> which you will need to cast to your OpenGL type).
You can avoid any risk of referencing invalid memory by dereferencing the pointer (if it is non-nil) and copying the value stored at the pointer to a variable in your Swift application.
With OpenGL ES being a pure set of C functions, I don't think passing a pointer of swift datatypes will work easily.
The following code will give you a hint of how to pass the index buffer.
var Indices: [GLubyte] = [
0, 1, 2,
2, 3, 0
]
var indexBuffer: GLuint = GLuint()
glGenBuffers(1, &indexBuffer)
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indexBuffer)
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), Indices.size(), Indices, GLenum(GL_STATIC_DRAW))
Reference: Here is a link with a working code. https://github.com/bradley/iOSSwiftOpenGL/blob/master/iOSSwiftOpenGL/OpenGLView.swift

Type 'Int' has no subscript members

I wrote a function:
func rms16(buffer: Int, bufferSize: Int) -> Float
{
let sum: Float = 0.0
let mySize: Int = bufferSize / sizeof(CShort)
var buffer_short: Int = buffer
for var i = 0; i < mySize; i++ {
sum += buffer_short[i] * 2
}
let sqrt1: Float = sqrtf(sum / Float(mySize))
return (sqrt1) / Float(mySize)
}
Above function in a for loop it show me error like this:
Type Int has no subscript members
Anyone tell me how can i fix it?
The buffer_short is an integer variable not an array of integer.
You need to change the first argument of your function to an array of integer, like:
func rms16(buffer: [Int], bufferSize: Int) -> Float
{
let sum: Float = 0.0
let mySize: Int = bufferSize / sizeof(CShort)
var buffer_short = buffer
for var i = 0; i < mySize; i++
{
sum += buffer_short[i] * 2
}
let sqrt1: Float = sqrtf(sum / Float(mySize))
return (sqrt1) / Float(mySize)
}
Your comments indicate that the first parameter should be a pointer to a character buffer. The corresponding Swift type is UnsafePointer<CChar>. Note also that you are multiplying by 2
instead of squaring in your Swift code, and that sum must be
declared as a variable.
So your Swift function would be
func rms16(buffer: UnsafePointer<CChar>, bufferSize: Int) -> Float
{
var sum: Float = 0.0
let mySize = bufferSize / sizeof(CShort)
// Create a pointer to a buffer of `CShort` elements from the given pointer:
let buffer_short = UnsafeBufferPointer<CShort>(start: UnsafePointer(buffer), count: mySize)
for var i = 0; i < mySize; i++ {
sum += pow(Float(buffer_short[i]), 2)
}
let sqrt1 = sqrtf(sum / Float(mySize))
return (sqrt1) / Float(mySize)
}
The summation loop can be reduced (!) to:
let sum = buffer_short.reduce(0.0, combine: { $0 + pow(Float($1), 2)} )

'String' is not convertible to 'Int' in Swift

In my adding function where answerLabel.text is it is giving me an error. It says 'String' is not convertible to 'Int' and I'm trying to get what I got from the secondStep2 and put in the parameters of my functions
//Adding Function
changingSignsLabel.text = "+"
let firstDenomInTextField:Double! = (firstDenominatorTextField.text as NSString).doubleValue
let firstNumInTextField:Double! = (firstNumeratorTextField.text as NSString).doubleValue
let firstWholeInTextField:Double! = (firstWholeNumberTextField.text as NSString).doubleValue
let secondDenomInTextField:Double! = (secondDenominatorTextField.text as NSString).doubleValue
let secondNumInTextField:Double! = (secondNumeratorTextField.text as NSString).doubleValue
let secondWholeInTextField:Double! = (secondWholeNumberTextField.text as NSString).doubleValue
var firstStep = firstDenomInTextField! * firstWholeInTextField! / firstDenomInTextField!
var secondStep = firstStep + firstNumInTextField! / firstDenomInTextField!
var thirdStep = secondDenomInTextField! * secondWholeInTextField! / secondDenomInTextField!
var fourthStep = thirdStep + secondNumInTextField! / secondDenomInTextField!
var calculatedAnswer = (secondStep + fourthStep)
answerLabel.hidden = false
var firstStep2 = calculatedAnswer / 1
var secondStep2 = "\(firstStep2 * 10 * 10)"
answerLabel.text = printSimplifiedFraction(Numerator: secondStep2)
My Function
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100)
{
var finalNumerator = numerator;
var finalDenominator = denominator;
var wholeNumbers:Int = numerator / denominator;
var remainder:Int = numerator % denominator;
//println("wholeNumbers = \(wholeNumbers), remainder = \(remainder)");
//println("\(denominator) % \(remainder) = \(denominator % remainder)");
if(remainder > 0)
{
// see if we can simply the fraction part as well
if(denominator % remainder == 0) // no remainder means remainder can be simplified further
{
finalDenominator = denominator / remainder;
finalNumerator = remainder / remainder;
}
else
{
finalNumerator = remainder;
finalDenominator = denominator;
}
}
if(wholeNumbers > 0 && remainder > 0)
{
// prints out whole number and fraction parts
println("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers) \(finalNumerator)/\(finalDenominator)");
}
else if (wholeNumbers > 0 && remainder == 0)
{
// prints out whole number only
println("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers)");
}
else
{
// prints out fraction part only
println("Simplified fraction of \(numerator)/\(denominator) = \(finalNumerator)/\(finalDenominator)");
}
}
My Question how do I get the function to accept my variable?
I believe this is what you want, first in your adding function it should be:
var firstStep2 = calculatedAnswer / 1
var secondStep2 = Int(firstStep2 * 10 * 10)
answerLabel.text = printSimplifiedFraction(Numerator: secondStep2)
Then your print... method should be changed like this (note that it's returning a String):
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100) -> String
{
// I haven't looked into this bit
...
if(wholeNumbers > 0 && remainder > 0)
{
return ("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers) \(finalNumerator)/\(finalDenominator)")
}
else if (wholeNumbers > 0 && remainder == 0)
{
return ("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers)")
}
else
{
return ("Simplified fraction of \(numerator)/\(denominator) = \(finalNumerator)/\(finalDenominator)")
}
}
Also, looking through your code I think you can simplify the logic quite a bit (I've also converted to Integers as you said you wanted in the comments):
let firstDenomInTextField = firstDenominatorTextField.text.toInt()
let firstNumInTextField = firstNumeratorTextField.text.toInt()
let firstWholeInTextField = firstWholeNumberTextField.text.toInt()
let secondDenomInTextField = secondDenominatorTextField.text.toInt()
let secondNumInTextField = secondNumeratorTextField.text.toInt()
let secondWholeInTextField = secondWholeNumberTextField.text.toInt()
var firstStep = firstWholeInTextField! + firstNumInTextField! / firstDenomInTextField!
var secondStep = secondWholeInTextField! + secondNumInTextField! / secondDenomInTextField!
var calculatedAnswer = (firstStep + secondStep)
var numerator = Int(calculatedAnswer * 10 * 10)
answerLabel.text = printSimplifiedFraction(Numerator: numerator)
Try this:
var str:String = "abc"
var a:Int? = str.toInt()
if (a != nil) {
printSimplifiedFraction(Numerator: str!)
}
And add a return value to your function
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100) ->String {
var finalNumerator = numerator;
var finalDenominator = denominator;
var wholeNumbers:Int = numerator / denominator;
var remainder:Int = numerator % denominator;
if(remainder > 0)
{
// see if we can simply the fraction part as well
if(denominator % remainder == 0) // no remainder means remainder can be simplified further
{
finalDenominator = denominator / remainder;
finalNumerator = remainder / remainder;
}
else
{
finalNumerator = remainder;
finalDenominator = denominator;
}
}
var result:String = "Simplified fraction of \(numerator)/\(denominator) = ";
if(wholeNumbers > 0 && remainder > 0)
{
// prints out whole number and fraction parts
result += "\(wholeNumbers) \(finalNumerator)/\(finalDenominator)"
}
else if (wholeNumbers > 0 && remainder == 0)
{
// prints out whole number only
result += "\(wholeNumbers)"
}
else
{
// prints out fraction part only
result += "\(finalNumerator)/\(finalDenominator)"
}
println("\(result)")
return result
}
this printSimplifiedFraction is not returning any value, but you are assigning to the answerLabel.text, i think this is the problem.
If you want to assign a value which is returned form fuction, add return type to the fuction and return a value.
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100) -> String {
//add end of your function
return yourValue;
}
Check this link
In Your Code do like this
var secondStep2 = (firstStep2 * 10 * 10)
answerLabel.text = printSimplifiedFraction(Numerator: secondStep2)
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100) -> String
{
var finalNumerator = numerator;
var finalDenominator = denominator;
var wholeNumbers:Int = numerator / denominator;
var remainder:Int = numerator % denominator;
//println("wholeNumbers = \(wholeNumbers), remainder = \(remainder)");
//println("\(denominator) % \(remainder) = \(denominator % remainder)");
if(remainder > 0)
{
// see if we can simply the fraction part as well
if(denominator % remainder == 0) // no remainder means remainder can be simplified further
{
finalDenominator = denominator / remainder;
finalNumerator = remainder / remainder;
}
else
{
finalNumerator = remainder;
finalDenominator = denominator;
}
}
var returnValue :String
if(wholeNumbers > 0 && remainder > 0)
{
returnValue = "Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers) \(finalNumerator)/\(finalDenominator)"
}
else if (wholeNumbers > 0 && remainder == 0)
{
returnValue = "Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers)"
}
else
{
returnValue = "Simplified fraction of \(numerator)/\(denominator) = \(finalNumerator)/\(finalDenominator)"
}
return returnValue
}

Resources