diff --git a/archimedean.cpp b/archimedean.cpp index e04ba00f..970ff848 100644 --- a/archimedean.cpp +++ b/archimedean.cpp @@ -1123,7 +1123,7 @@ void show() { if(archimedean) { dialog::addSelItem(XLAT("size of the world"), current.world_size(), 0); - dialog::addSelItem(XLAT("edge length"), current.get_class() == gcEuclid ? (fts(current.edgelength) + XLAT(" (arbitrary)")) : fts6(current.edgelength), 0); + dialog::addSelItem(XLAT("edge length"), current.get_class() == gcEuclid ? (fts(current.edgelength) + XLAT(" (arbitrary)")) : fts(current.edgelength), 0); dialog::addItem(XLAT("color by symmetries"), 't'); dialog::add_action(setcanvas('A')); diff --git a/config.cpp b/config.cpp index d7104bd3..6a629e7c 100644 --- a/config.cpp +++ b/config.cpp @@ -1141,7 +1141,7 @@ void explain_detail() { "Objects at distance less than %1 absolute units " "from the center will be displayed with high " "detail, and at distance at least %2 with low detail.", - fts3(geom3::highdetail), fts3(geom3::middetail) + fts(geom3::highdetail), fts(geom3::middetail) )); } @@ -1168,7 +1168,7 @@ void showStereo() { string modenames[4] = { "OFF", "anaglyph", "side-by-side", "ODS" }; dialog::addSelItem(XLAT("stereo mode"), XLAT(modenames[vid.stereo_mode]), 'm'); - dialog::addSelItem(XLAT("pupillary distance"), fts3(vid.ipd), 'e'); + dialog::addSelItem(XLAT("pupillary distance"), fts(vid.ipd), 'e'); switch(vid.stereo_mode) { case sAnaglyph: @@ -1288,33 +1288,33 @@ void show3D() { } if(WDIM == 2) { - dialog::addSelItem(XLAT(GDIM == 2 ? "Camera level above the plane" : "Z shift"), fts3(camera), 'c'); - dialog::addSelItem(XLAT("Ground level below the plane"), fts3(depth), 'g'); + dialog::addSelItem(XLAT(GDIM == 2 ? "Camera level above the plane" : "Z shift"), fts(camera), 'c'); + dialog::addSelItem(XLAT("Ground level below the plane"), fts(depth), 'g'); - dialog::addSelItem(XLAT("Projection at the ground level"), fts3(vid.alpha), 'a'); + dialog::addSelItem(XLAT("Projection at the ground level"), fts(vid.alpha), 'a'); dialog::addBreak(50); - dialog::addSelItem(XLAT("Height of walls"), fts3(wall_height), 'w'); + dialog::addSelItem(XLAT("Height of walls"), fts(wall_height), 'w'); - dialog::addSelItem(XLAT("Rock-III to wall ratio"), fts3(rock_wall_ratio), 'r'); - dialog::addSelItem(XLAT("Human to wall ratio"), fts3(human_wall_ratio), 'h'); - dialog::addSelItem(XLAT("Level of water surface"), fts3(lake_top), 'l'); - dialog::addSelItem(XLAT("Level of water bottom"), fts3(lake_bottom), 'k'); + dialog::addSelItem(XLAT("Rock-III to wall ratio"), fts(rock_wall_ratio), 'r'); + dialog::addSelItem(XLAT("Human to wall ratio"), fts(human_wall_ratio), 'h'); + dialog::addSelItem(XLAT("Level of water surface"), fts(lake_top), 'l'); + dialog::addSelItem(XLAT("Level of water bottom"), fts(lake_bottom), 'k'); } else { - dialog::addSelItem(XLAT("Creature scale"), fts3(creature_scale), 'c'); - dialog::addSelItem(XLAT("Height to width"), fts3(height_width), 'h'); + dialog::addSelItem(XLAT("Creature scale"), fts(creature_scale), 'c'); + dialog::addSelItem(XLAT("Height to width"), fts(height_width), 'h'); menuitem_sightrange('s'); } dialog::addBreak(50); - dialog::addSelItem(XLAT(DIM == 3 && WDIM == 2 ? "Y shift" : "third person perspective"), fts3(vid.yshift), 'y'); + dialog::addSelItem(XLAT(DIM == 3 && WDIM == 2 ? "Y shift" : "third person perspective"), fts(vid.yshift), 'y'); if(DIM == 3) { dialog::addSelItem(XLAT("mouse aiming sensitivity"), fts(mouseaim_sensitivity), 'a'); dialog::add_action([] () { dialog::editNumber(mouseaim_sensitivity, -1, 1, 0.002, 0.01, XLAT("mouse aiming sensitivity"), "set to 0 to disable"); }); } - dialog::addSelItem(XLAT("camera rotation"), fts3(vid.camera_angle), 's'); + dialog::addSelItem(XLAT("camera rotation"), fts(vid.camera_angle), 's'); if(DIM == 2) { dialog::addSelItem(XLAT("fixed facing"), vid.fixed_facing ? fts(vid.fixed_facing_dir) : XLAT("OFF"), 'f'); dialog::add_action([] () { vid.fixed_facing = !vid.fixed_facing; @@ -1335,7 +1335,7 @@ void show3D() { #if MAXMDIM >= 4 if(DIM == 3) add_edit_fov('f'); if(DIM == 3) { - dialog::addSelItem(XLAT("radar size"), fts3(vid.radarsize), 'r'); + dialog::addSelItem(XLAT("radar size"), fts(vid.radarsize), 'r'); dialog::add_action([] () { dialog::editNumber(vid.radarsize, 0, 360, 15, 90, "", "set to 0 to disable"); }); @@ -1409,10 +1409,10 @@ void show3D() { "other equidistant surface below it) is viewed at an angle of %3 " "(the tangent of the angle between the point in " "the center of your vision and a faraway location is 1/cosh(c) = %4).", - fts3(camera), - fts3(depth), - fts3(atan(1/cosh(camera))*2/degree), - fts3(1/cosh(camera))) : XLAT("Look from behind.")); + fts(camera), + fts(depth), + fts(atan(1/cosh(camera))*2/degree), + fts(1/cosh(camera))) : XLAT("Look from behind.")); if(DIM == 3 && pmodel == mdPerspective) dialog::extra_options = [] () { dialog::addBoolItem_action(XLAT("reduce if walls on the way"), vid.use_wall_radar, 'R'); }; @@ -1436,7 +1436,7 @@ void show3D() { "distances.)" , - fts3(depth), fts3(cosh(depth)))); + fts(depth), fts(cosh(depth)))); // mention absolute units }; else if(uni == 'a' && WDIM == 2) @@ -1448,7 +1448,7 @@ void show3D() { dialog::addHelp(XLAT( "The height of walls, in absolute units. For the current values of g and c, " "wall height of %1 absolute units corresponds to projection value of %2.", - fts3(actual_wall_height()), fts3(factor_to_projection(geom3::WALL)))); + fts(actual_wall_height()), fts(factor_to_projection(geom3::WALL)))); dialog::addBoolItem(XLAT("auto-adjust in Goldberg grids"), geom3::gp_autoscale_heights, 'O'); dialog::add_action([] () { geom3::gp_autoscale_heights = !geom3::gp_autoscale_heights; @@ -1471,8 +1471,8 @@ void show3D() { "The ratio of Rock III to walls is %1, so Rock III are %2 absolute units high. " "Length of paths on the Rock III level is %3 of the corresponding length on the " "ground level.", - fts3(rock_wall_ratio), fts3(wall_height * rock_wall_ratio), - fts3(cosh(depth - wall_height * rock_wall_ratio) / cosh(depth)))); + fts(rock_wall_ratio), fts(wall_height * rock_wall_ratio), + fts(cosh(depth - wall_height * rock_wall_ratio) / cosh(depth)))); }, dialog::reaction = delayed_geo_reset; else if(uni == 'h' && WDIM == 2) @@ -1482,8 +1482,8 @@ void show3D() { "Humans are %1 " "absolute units high. Your head travels %2 times the distance travelled by your " "feet.", - fts3(wall_height * human_wall_ratio), - fts3(cosh(depth - wall_height * human_wall_ratio) / cosh(depth))) + fts(wall_height * human_wall_ratio), + fts(cosh(depth - wall_height * human_wall_ratio) / cosh(depth))) ); }; else if(uni == 'h' && WDIM == 3) @@ -1651,7 +1651,7 @@ void show_color_dialog() { dialog::addColorItem(XLAT("standard grid color"), stdgridcolor, 'g'); dialog::add_action([] () { vid.grid = true; dialog::openColorDialog(stdgridcolor); dialog::dialogflags |= sm::SIDE; }); - dialog::addSelItem(XLAT("brightness behind the sphere"), fts3(backbrightness), 'i'); + dialog::addSelItem(XLAT("brightness behind the sphere"), fts(backbrightness), 'i'); dialog::add_action([] () { dialog::editNumber(backbrightness, 0, 1, .01, 0.25, XLAT("brightness behind the sphere"), XLAT("In the orthogonal projection, objects on the other side of the sphere are drawn darker.")); dialog::bound_low(0); }); diff --git a/conformal.cpp b/conformal.cpp index 116a6fb8..86ee420b 100644 --- a/conformal.cpp +++ b/conformal.cpp @@ -758,7 +758,7 @@ namespace conformal { if(among(pmodel, mdDisk, mdBall, mdHyperboloid, mdRotatedHyperboles)) { dialog::addSelItem(XLAT("projection distance"), - fts3(vid.alpha) + " (" + current_proj_name() + ")", 'p'); + fts(vid.alpha) + " (" + current_proj_name() + ")", 'p'); } if(model_has_orientation()) { @@ -798,14 +798,14 @@ namespace conformal { if(pmodel == mdPolynomial) { dialog::addSelItem(XLAT("coefficient"), - fts4(polygonal::coefr[polygonal::coefid]), 'x'); + fts(polygonal::coefr[polygonal::coefid]), 'x'); dialog::add_action([] () { polygonal::maxcoef = max(polygonal::maxcoef, polygonal::coefid); int ci = polygonal::coefid + 1; dialog::editNumber(polygonal::coefr[polygonal::coefid], -10, 10, .01/ci/ci, 0, XLAT("coefficient"), ""); }); dialog::addSelItem(XLAT("coefficient (imaginary)"), - fts4(polygonal::coefi[polygonal::coefid]), 'y'); + fts(polygonal::coefi[polygonal::coefid]), 'y'); dialog::add_action([] () { polygonal::maxcoef = max(polygonal::maxcoef, polygonal::coefid); int ci = polygonal::coefid + 1; @@ -830,7 +830,7 @@ namespace conformal { } if(pmodel == mdBall) { - dialog::addSelItem(XLAT("projection in ball model"), fts3(vid.ballproj), 'x'); + dialog::addSelItem(XLAT("projection in ball model"), fts(vid.ballproj), 'x'); dialog::add_action([] () { dialog::editNumber(vid.ballproj, 0, 100, .1, 0, XLAT("projection in ball model"), "This parameter affects the ball model the same way as the projection parameter affects the disk model."); @@ -857,19 +857,19 @@ namespace conformal { } if(pmodel == mdBall || pmodel == mdHyperboloid || pmodel == mdHemisphere || (pmodel == mdSpiral && spiral_cone != 360)) { - dialog::addSelItem(XLAT("camera rotation in 3D models"), fts3(vid.ballangle) + "°", 'b'); + dialog::addSelItem(XLAT("camera rotation in 3D models"), fts(vid.ballangle) + "°", 'b'); dialog::add_action(config_camera_rotation); } if(pmodel == mdHyperboloid) { - dialog::addSelItem(XLAT("maximum z coordinate to show"), fts3(top_z), 'l'); + dialog::addSelItem(XLAT("maximum z coordinate to show"), fts(top_z), 'l'); dialog::add_action([](){ dialog::editNumber(top_z, 1, 20, 0.25, 4, XLAT("maximum z coordinate to show"), ""); }); } if(model_has_transition()) { - dialog::addSelItem(XLAT("model transition"), fts3(model_transition), 't'); + dialog::addSelItem(XLAT("model transition"), fts(model_transition), 't'); dialog::add_action([]() { dialog::editNumber(model_transition, 0, 1, 0.1, 1, XLAT("model transition"), "You can change this parameter for a transition from another model to this one." @@ -878,14 +878,14 @@ namespace conformal { } if(among(pmodel, mdJoukowsky, mdJoukowskyInverted, mdSpiral) && DIM == 2) { - dialog::addSelItem(XLAT("Möbius transformations"), fts3(vid.skiprope) + "°", 'S'); + dialog::addSelItem(XLAT("Möbius transformations"), fts(vid.skiprope) + "°", 'S'); dialog::add_action([](){ dialog::editNumber(vid.skiprope, 0, 360, 15, 0, XLAT("Möbius transformations"), ""); }); } if(pmodel == mdHemisphere && euclid) { - dialog::addSelItem(XLAT("parameter"), fts3(vid.euclid_to_sphere), 'l'); + dialog::addSelItem(XLAT("parameter"), fts(vid.euclid_to_sphere), 'l'); dialog::add_action([] () { dialog::editNumber(vid.euclid_to_sphere, 0, 10, .1, 1, XLAT("parameter"), "Stereographic projection to a sphere. Choose the radius of the sphere." @@ -895,7 +895,7 @@ namespace conformal { } if(pmodel == mdTwoPoint) { - dialog::addSelItem(XLAT("parameter"), fts3(vid.twopoint_param), 'b'); + dialog::addSelItem(XLAT("parameter"), fts(vid.twopoint_param), 'b'); dialog::add_action([](){ dialog::editNumber(vid.twopoint_param, 0, 10, .1, 1, XLAT("parameter"), "This model maps the world so that the distances from two points " @@ -952,7 +952,7 @@ namespace conformal { } } - dialog::addSelItem(XLAT("vertical stretch"), fts3(vid.stretch), 's'); + dialog::addSelItem(XLAT("vertical stretch"), fts(vid.stretch), 's'); dialog::addBoolItem(XLAT("use GPU to compute projections"), vid.consider_shader_projection, 'G'); if(vid.consider_shader_projection && !shaderside_projection) diff --git a/dialogs.cpp b/dialogs.cpp index 9bcd2d71..4f53c617 100644 --- a/dialogs.cpp +++ b/dialogs.cpp @@ -604,7 +604,7 @@ namespace dialog { string disp(ld x) { if(dialogflags & sm::HEXEDIT) return "0x" + itsh(x); else if(ne.intval) return its(ldtoint(x)); - else if(ne.vmax-ne.vmin < 1) return fts4(x); else return fts(x); } + else return fts(x); } reaction_t reaction; reaction_t reaction_final; diff --git a/expansion.cpp b/expansion.cpp index ee01299c..e55853c7 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -714,9 +714,7 @@ void expansion_analyzer::view_distances_dialog() { } else dialog::addBreak(100); - char buf[20]; - snprintf(buf, 20, "%.8lf", (double) get_growth()); - dialog::addInfo("Θ(" + string(buf) + "...ᵈ)", forecolor); + dialog::addInfo("Θ(" + fts(get_growth(), 8) + "...ᵈ)", forecolor); } } @@ -808,7 +806,7 @@ int expansion_readArgs() { for(int c: expansion.children[i]) printf(" %d", c); printf("\n"); } - printf("growth = %lf\n", (double) expansion.get_growth()); + println(hlog, "growth = ", expansion.get_growth()); expansion.find_coefficients(); if(expansion.coefficients_known == 2) { printf("coefficients:"); for(int x: expansion.coef) printf(" %d", x); diff --git a/geom-exp.cpp b/geom-exp.cpp index 0de8cae3..93a2d28a 100644 --- a/geom-exp.cpp +++ b/geom-exp.cpp @@ -750,7 +750,7 @@ void showEuclideanMenu() { dialog::addSelItem(XLAT("size of the world"), #if CAP_BT - binarytiling ? fts4(8 * M_PI * sqrt(2) * log(2) / pow(vid.binary_width, WDIM-1)) + " exp(∞)" : + binarytiling ? fts(8 * M_PI * sqrt(2) * log(2) / pow(vid.binary_width, WDIM-1), 4) + " exp(∞)" : #endif #if CAP_ARCM archimedean ? arcm::current.world_size() : diff --git a/hyper.h b/hyper.h index fe827a5b..789077c0 100644 --- a/hyper.h +++ b/hyper.h @@ -3733,7 +3733,8 @@ extern const hyperpoint Hypc; ld det(const transmatrix& T); void queuechr(const hyperpoint& h, int size, char chr, color_t col, int frame = 0); -string fts(float x); +string fts(ld x, int prec = 6); + bool model_needs_depth(); hyperpoint hpxy(ld x, ld y); @@ -3849,8 +3850,6 @@ typedef vector> saverlist; extern saverlist savers; -extern string ftssmart(ld x); - string itsh(int i); #if CAP_CONFIG @@ -3929,7 +3928,7 @@ template<> struct saver : dsaver { template<> struct saver : dsaver { saver(ld& val) : dsaver(val) { } - string save() { return ftssmart(val); } + string save() { return fts(val, 10); } void load(const string& s) { if(s == "0.0000000000e+000") ; // ignore! else val = atof(s.c_str()); diff --git a/irregular.cpp b/irregular.cpp index 01c1c4b6..a0df1fa9 100644 --- a/irregular.cpp +++ b/irregular.cpp @@ -383,7 +383,7 @@ bool step(int delta) { ld median = edgelens[isize(edgelens) / 2]; ld minedge = median * quality; - status[3] = XLAT("median edge: %1 minimum: %2", fts4(median), fts4(edgelens[0])); + status[3] = XLAT("median edge: %1 minimum: %2", fts(median), fts(edgelens[0])); if(!bitruncations_performed && edgelens[0] < minedge) { if(rearrange_index >= rearrange_max_attempts) { runlevel = 0; break; diff --git a/mapeditor.cpp b/mapeditor.cpp index 34fe4a35..a1882b0a 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -1326,7 +1326,7 @@ namespace mapeditor { displayButton(8, 8+fs*16, XLAT("p = grid color"), 'p', 0); else displayButton(8, 8+fs*16, XLAT("p = color"), 'p', 0); - displayButton(8, 8+fs*4, XLAT("b = brush size: %1", fts4(texture::penwidth)), 'b', 0); + displayButton(8, 8+fs*4, XLAT("b = brush size: %1", fts(texture::penwidth)), 'b', 0); displayButton(8, 8+fs*5, XLAT("u = undo"), 'u', 0); displaymm('d', 8, 8+fs*7, 2, vid.fsize, XLAT("d = draw"), 0); displaymm('l', 8, 8+fs*8, 2, vid.fsize, XLAT("l = line"), 0); @@ -1363,25 +1363,25 @@ namespace mapeditor { if(!mouseout()) { transmatrix T = inverse(drawtrans * rgpushxto0(ccenter)); hyperpoint mh = spintox(gpushxto0(ccenter) * coldcenter) * T * mouseh; - displayfr(vid.xres-8, vid.yres-8-fs*7, 2, vid.fsize, XLAT("x: %1", fts4(mh[0])), 0xC0C0C0, 16); - displayfr(vid.xres-8, vid.yres-8-fs*6, 2, vid.fsize, XLAT("y: %1", fts4(mh[1])), 0xC0C0C0, 16); - displayfr(vid.xres-8, vid.yres-8-fs*5, 2, vid.fsize, XLAT("z: %1", fts4(mh[2])) + (DIM == 3 ? "/" + fts4(mh[3]) : ""), 0xC0C0C0, 16); + displayfr(vid.xres-8, vid.yres-8-fs*7, 2, vid.fsize, XLAT("x: %1", fts(mh[0],4)), 0xC0C0C0, 16); + displayfr(vid.xres-8, vid.yres-8-fs*6, 2, vid.fsize, XLAT("y: %1", fts(mh[1],4)), 0xC0C0C0, 16); + displayfr(vid.xres-8, vid.yres-8-fs*5, 2, vid.fsize, XLAT("z: %1", fts(mh[2],4)) + (DIM == 3 ? "/" + fts(mh[3], 4) : ""), 0xC0C0C0, 16); if(DIM == 3) - displayfr(vid.xres-8, vid.yres-8-fs*4, 2, vid.fsize, XLAT("w: %1", fts4(mh[3])), 0xC0C0C0, 16); - displayfr(vid.xres-8, vid.yres-8-fs*3, 2, vid.fsize, XLAT("r: %1", fts4(hdist0(mh))), 0xC0C0C0, 16); + displayfr(vid.xres-8, vid.yres-8-fs*4, 2, vid.fsize, XLAT("w: %1", fts(mh[3],4)), 0xC0C0C0, 16); + displayfr(vid.xres-8, vid.yres-8-fs*3, 2, vid.fsize, XLAT("r: %1", fts(hdist0(mh),4)), 0xC0C0C0, 16); if(DIM == 3) { - displayfr(vid.xres-8, vid.yres-8-fs, 2, vid.fsize, XLAT("ϕ: %1°", fts4(-atan2(mh[2], hypot_d(2, mh)) / degree)), 0xC0C0C0, 16); - displayfr(vid.xres-8, vid.yres-8-fs*2, 2, vid.fsize, XLAT("λ: %1°", fts4(-atan2(mh[1], mh[0]) / degree)), 0xC0C0C0, 16); + displayfr(vid.xres-8, vid.yres-8-fs, 2, vid.fsize, XLAT("ϕ: %1°", fts(-atan2(mh[2], hypot_d(2, mh)) / degree,4)), 0xC0C0C0, 16); + displayfr(vid.xres-8, vid.yres-8-fs*2, 2, vid.fsize, XLAT("λ: %1°", fts(-atan2(mh[1], mh[0]) / degree,4)), 0xC0C0C0, 16); } else { - displayfr(vid.xres-8, vid.yres-8-fs*2, 2, vid.fsize, XLAT("ϕ: %1°", fts4(-atan2(mh[1], mh[0]) / degree)), 0xC0C0C0, 16); + displayfr(vid.xres-8, vid.yres-8-fs*2, 2, vid.fsize, XLAT("ϕ: %1°", fts(-atan2(mh[1], mh[0]) / degree,4)), 0xC0C0C0, 16); } } if(us) { auto& sh = us->d[dslayer].sh; if(sh.e >= sh.s + 3) - displayButton(vid.xres-8, vid.yres-8-fs*8, XLAT("area: %1", area_in_pi ? fts4(compute_area(sh) / M_PI) + "π" : fts4(compute_area(sh))), 'w', 16); + displayButton(vid.xres-8, vid.yres-8-fs*8, XLAT("area: %1", area_in_pi ? fts(compute_area(sh) / M_PI, 4) + "π" : fts(compute_area(sh), 4)), 'w', 16); } diff --git a/rug.cpp b/rug.cpp index 646aed0c..91090563 100644 --- a/rug.cpp +++ b/rug.cpp @@ -1854,16 +1854,16 @@ void show() { if(!rug::rugged) dialog::addSelItem(XLAT("native geometry"), geometry_name(gwhere), 'n'); else - dialog::addSelItem(XLAT("radar"), radar_distance == RADAR_INF ? "∞" : fts4(radar_distance), 'r'); + dialog::addSelItem(XLAT("radar"), radar_distance == RADAR_INF ? "∞" : fts(radar_distance, 4), 'r'); dialog::addSelItem(XLAT("model scale factor"), fts(modelscale), 'm'); if(rug::rugged) dialog::addSelItem(XLAT("model iterations"), its(queueiter), 0); dialog::addItem(XLAT("stereo vision config"), 'f'); // dialog::addSelItem(XLAT("protractor"), fts(protractor * 180 / M_PI) + "°", 'f'); if(!good_shape) { - dialog::addSelItem(XLAT("maximum error"), ftsg(err_zero), 'e'); + dialog::addSelItem(XLAT("maximum error"), fts(err_zero), 'e'); if(rug::rugged) - dialog::lastItem().value += " (" + ftsg(err_zero_current) + ")"; + dialog::lastItem().value += " (" + fts(err_zero_current) + ")"; } dialog::addSelItem(XLAT("automatic move speed"), fts(ruggo), 'G'); dialog::addSelItem(XLAT("anti-crossing"), fts(anticusp_factor), 'A'); diff --git a/textures.cpp b/textures.cpp index 9aed0d68..88a284fc 100644 --- a/textures.cpp +++ b/textures.cpp @@ -873,7 +873,7 @@ bool texture_config::save() { for(auto& t: a.second.triangles) for(auto& v: t.tv) for(int i=0; i<3; i++) { - texture_tuner += ftssmart(v[i]); + texture_tuner += fts(v[i]); texture_tuner += ';'; } } diff --git a/util.cpp b/util.cpp index 1a08e0d0..548bad94 100644 --- a/util.cpp +++ b/util.cpp @@ -26,17 +26,12 @@ int SDL_GetTicks() { long double sqr(long double x) { return x*x; } string its(int i) { char buf[64]; sprintf(buf, "%d", i); return buf; } -string fts(float x) { char buf[64]; sprintf(buf, "%4.2f", x); return buf; } -string fts3(float x) { char buf[64]; sprintf(buf, "%5.3f", x); return buf; } -string fts4(float x) { char buf[64]; sprintf(buf, "%6.4f", x); return buf; } -string fts6(float x) { char buf[64]; sprintf(buf, "%8.6f", x); return buf; } -string ftsg(float x) { char buf[64]; sprintf(buf, "%4.2g", x); return buf; } -string ftssmart(ld x) { - if(x == int(x)) return its(int(x)); - if(abs(x) > 1) return fts4(x); - char buf[64]; sprintf(buf, "%.10e", (float) x); - return buf; +string fts(ld x, int prec) { + std::stringstream ss; + ss.precision(prec); + ss << x; + return ss.str(); } bool scan(fhstream& hs, int& i) { return fscanf(hs.f, "%d", &i) == 1; }