diff --git a/archimedean.cpp b/archimedean.cpp
index 8d08fa19..d41d52d2 100644
--- a/archimedean.cpp
+++ b/archimedean.cpp
@@ -66,6 +66,8 @@ struct archimedean_tiling {
   void regroup();
   string world_size();
   
+  eGeometryClass get_class();
+  
   ld scale();
   };
 
@@ -108,6 +110,9 @@ void archimedean_tiling::make_match(int a, int i, int b, int j) {
 
 void archimedean_tiling::prepare() {
 
+  euclidean_angle_sum = 0;
+  for(int f: faces) euclidean_angle_sum += (f-2.) / f;
+
   for(int i: faces) if(i > MAX_EDGE) {
     errormsg = XLAT("currently no more than %1 edges", its(MAX_EDGE));
     errors++;
@@ -252,9 +257,6 @@ void archimedean_tiling::prepare() {
     }
   
   regroup();
-  
-  euclidean_angle_sum = 0;
-  for(int f: faces) euclidean_angle_sum += (f-2.) / f;
   }
 
 void archimedean_tiling::regroup() {
@@ -299,12 +301,16 @@ void archimedean_tiling::regroup() {
     } )
   }
 
+eGeometryClass archimedean_tiling::get_class() {
+  if(euclidean_angle_sum < 1.999999) return gcSphere;
+  else if(euclidean_angle_sum > 2.000001) return gcHyperbolic;
+  else return gcEuclid;
+  }
+
 void archimedean_tiling::compute_geometry() {
-  if(euclidean_angle_sum < 1.999999) ginf[gArchimedean].cclass = gcSphere;
-  else if(euclidean_angle_sum > 2.000001) ginf[gArchimedean].cclass = gcHyperbolic;
-  else ginf[gArchimedean].cclass = gcEuclid;
+  ginf[gArchimedean].cclass = get_class();
   
-  SDEBUG( printf("euclidean_angle_sum = %lf\n", double(euclidean_angle_sum)); )
+  SDEBUG( printf("euclidean_angle_sum = %f\n", float(euclidean_angle_sum)); )
   
   dynamicval<eGeometry> dv(geometry, gArchimedean);
   
@@ -340,28 +346,34 @@ void archimedean_tiling::compute_geometry() {
     ld alpha_total = 0;
 
     for(int i=0; i<N; i++) {
-      ld crmin = 0, crmax = sphere ? M_PI : 10;
+      ld crmin = 0, crmax = sphere ? M_PI/2 : 10;
+      ld el = 0;
       for(int q=0; q<100; q++) {
         circumradius[i] = (crmin + crmax) / 2;
         hyperpoint p1 = xpush0(circumradius[i]);
         hyperpoint p2 = spin(2 * M_PI / faces[i]) * p1;
         inradius[i] = hdist0(mid(p1, p2));
-        if(hdist(p1, p2) > edgelength) crmax = circumradius[i];
+        el = hdist(p1, p2);
+        if(el > edgelength) crmax = circumradius[i];
         else crmin = circumradius[i];
         }
+      if(el < edgelength - 1e-3) alpha_total += 100; // could not make an edge that long
       hyperpoint h = xpush(edgelength/2) * xspinpush0(M_PI/2, inradius[i]);
-      alphas[i] = atan2(-h[1], h[0]);
+      ld a = atan2(-h[1], h[0]);
+      if(a < 0) a += 2 * M_PI;
+      alphas[i] = a;
+      // printf("  H = %s alp = %f\n", display(h), (float) atan2(-h[1], h[0]));
       alpha_total += alphas[i];
       }
     
-    // printf("el = %lf alpha = %lf\n", double(edgelength), double(alpha_total));
+    // printf("el = %f alpha = %f\n", float(edgelength), float(alpha_total));
 
     if(sphere ^ (alpha_total > M_PI)) elmin = edgelength;
     else elmax = edgelength;
     if(euclid) break;
     }
   
-  SDEBUG( printf("computed edgelength = %lf\n", double(edgelength)); )
+  SDEBUG( printf("computed edgelength = %f\n", float(edgelength)); )
   
   triangles.clear();
   triangles.resize(2*N+2);
@@ -384,7 +396,7 @@ void archimedean_tiling::compute_geometry() {
 
   SDEBUG( for(auto& ts: triangles) {
     printf("T");
-    for(auto& t: ts) printf(" %lf@%lf", double(t.first), double(t.second));
+    for(auto& t: ts) printf(" %f@%f", float(t.first), float(t.second));
     printf("\n");
     } )
   
@@ -1010,6 +1022,11 @@ void show() {
     
     dialog::addBreak(100);
     dialog::addSelItem(XLAT("full angle"), fts(edited.euclidean_angle_sum * 180) + "°", 0);
+    dialog::addSelItem(XLAT("size of the world"), edited.world_size(), 0);
+
+    edited.compute_geometry();
+    dialog::addSelItem(XLAT("edge length"), fts(edited.edgelength) + (edited.get_class() == gcEuclid ? XLAT(" (arbitrary)") : ""), 0);
+    current.compute_geometry();
     dialog::addBreak(100);
     }
   else {
@@ -1048,6 +1065,9 @@ 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::addItem(XLAT("color by symmetries"), 't');
       dialog::add_action([] () {
         firstland = specialland = laCanvas;
@@ -1093,6 +1113,8 @@ void show() {
   }
 
 string archimedean_tiling::world_size() {
+  if(get_class() == gcEuclid) return "∞";
+
   int nom = 2 - N, denom = 2;
   for(int f: faces) {
     int g = gcd(denom, f);
@@ -1110,11 +1132,13 @@ string archimedean_tiling::world_size() {
   anom /= g; adenom /= g;
   if(adenom < 0) anom = -anom, adenom = -adenom;
   string s;
-  if(anom < 0) s = "exp(∞)*", anom = -anom;
+  bool hyp = (anom < 0);
+  if(hyp) anom = -anom;
   if(adenom > 1) 
     s += its(anom) + "/" + its(adenom);
   else
     s += its(anom);
+  if(hyp) s += " exp(∞)";
   return s;
   }
 
diff --git a/geom-exp.cpp b/geom-exp.cpp
index a2a31b3a..49cceb73 100644
--- a/geom-exp.cpp
+++ b/geom-exp.cpp
@@ -355,10 +355,9 @@ void showEuclideanMenu() {
     dialog::addSelItem(XLAT("quotient space"), XLAT(qstring), 0);
     
     dialog::addSelItem(XLAT("size of the world"), 
-      (archimedean && euclid) ? "∞" :
       archimedean ? arcm::current.world_size() :
       (archimedean && sphere) ? its(isize(currentmap->allcells())) :
-      worldsize < 0 ? "exp(∞)*" + (nom%denom ? its(nom)+"/"+its(-denom) : its(-worldsize)): 
+      worldsize < 0 ? (nom%denom ? its(nom)+"/"+its(-denom) : its(-worldsize)) + " exp(∞)": 
       worldsize == 0 ? "∞" :
       its(worldsize),
       '3');
diff --git a/util.cpp b/util.cpp
index 83c09ad7..857048f2 100644
--- a/util.cpp
+++ b/util.cpp
@@ -29,6 +29,7 @@ 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) {